// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
 *******************************************************************************
 * Copyright (C) 2001-2016, International Business Machines Corporation and
 * others. All Rights Reserved.
 *******************************************************************************
 */

/**
 * Port From:   ICU4C v1.8.1 : format : NumberFormatTest
 * Source File: $ICU4oot/source/test/intltest/numfmtst.cpp
 **/

package com.ibm.icu.dev.test.format;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.text.AttributedCharacterIterator;
import java.text.FieldPosition;
import java.text.Format;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import java.util.Set;

import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.dev.test.TestUtil;
import com.ibm.icu.dev.test.format.IntlTestDecimalFormatAPIC.FieldContainer;
import com.ibm.icu.impl.DontCareFieldPosition;
import com.ibm.icu.impl.ICUConfig;
import com.ibm.icu.impl.LocaleUtility;
import com.ibm.icu.impl.data.ResourceReader;
import com.ibm.icu.impl.data.TokenIterator;
import com.ibm.icu.impl.number.PatternStringUtils;
import com.ibm.icu.math.BigDecimal;
import com.ibm.icu.math.MathContext;
import com.ibm.icu.text.CompactDecimalFormat;
import com.ibm.icu.text.CurrencyPluralInfo;
import com.ibm.icu.text.DecimalFormat;
import com.ibm.icu.text.DecimalFormatSymbols;
import com.ibm.icu.text.DisplayContext;
import com.ibm.icu.text.MeasureFormat;
import com.ibm.icu.text.NumberFormat;
import com.ibm.icu.text.NumberFormat.NumberFormatFactory;
import com.ibm.icu.text.NumberFormat.SimpleNumberFormatFactory;
import com.ibm.icu.text.NumberingSystem;
import com.ibm.icu.text.RuleBasedNumberFormat;
import com.ibm.icu.text.UnicodeSet;
import com.ibm.icu.util.Currency;
import com.ibm.icu.util.Currency.CurrencyUsage;
import com.ibm.icu.util.CurrencyAmount;
import com.ibm.icu.util.ULocale;

@RunWith(JUnit4.class)
public class NumberFormatTest extends TestFmwk {

    @Test
    public void TestRoundingScientific10542() {
        DecimalFormat format =
                new DecimalFormat("0.00E0");

        int[] roundingModes = {
              BigDecimal.ROUND_CEILING,
              BigDecimal.ROUND_DOWN,
              BigDecimal.ROUND_FLOOR,
              BigDecimal.ROUND_HALF_DOWN,
              BigDecimal.ROUND_HALF_EVEN,
              BigDecimal.ROUND_HALF_UP,
              BigDecimal.ROUND_UP};
        String[] descriptions = {
                "Round Ceiling",
                "Round Down",
                "Round Floor",
                "Round half down",
                "Round half even",
                "Round half up",
                "Round up"};

        double[] values = {-0.003006, -0.003005, -0.003004, 0.003014, 0.003015, 0.003016};
        // The order of these expected values correspond to the order of roundingModes and the order of values.
        String[][] expected = {
                {"-3.00E-3", "-3.00E-3", "-3.00E-3", "3.02E-3", "3.02E-3", "3.02E-3"},
                {"-3.00E-3", "-3.00E-3", "-3.00E-3", "3.01E-3", "3.01E-3", "3.01E-3"},
                {"-3.01E-3", "-3.01E-3", "-3.01E-3", "3.01E-3", "3.01E-3", "3.01E-3"},
                {"-3.01E-3", "-3.00E-3", "-3.00E-3", "3.01E-3", "3.01E-3", "3.02E-3"},
                {"-3.01E-3", "-3.00E-3", "-3.00E-3", "3.01E-3", "3.02E-3", "3.02E-3"},
                {"-3.01E-3", "-3.01E-3", "-3.00E-3", "3.01E-3", "3.02E-3", "3.02E-3"},
                {"-3.01E-3", "-3.01E-3", "-3.01E-3", "3.02E-3", "3.02E-3", "3.02E-3"}};
        verifyRounding(format, values, expected, roundingModes, descriptions);
        values = new double[]{-3006.0, -3005, -3004, 3014, 3015, 3016};
        // The order of these expected values correspond to the order of roundingModes and the order of values.
        expected = new String[][]{
                {"-3.00E3", "-3.00E3", "-3.00E3", "3.02E3", "3.02E3", "3.02E3"},
                {"-3.00E3", "-3.00E3", "-3.00E3", "3.01E3", "3.01E3", "3.01E3"},
                {"-3.01E3", "-3.01E3", "-3.01E3", "3.01E3", "3.01E3", "3.01E3"},
                {"-3.01E3", "-3.00E3", "-3.00E3", "3.01E3", "3.01E3", "3.02E3"},
                {"-3.01E3", "-3.00E3", "-3.00E3", "3.01E3", "3.02E3", "3.02E3"},
                {"-3.01E3", "-3.01E3", "-3.00E3", "3.01E3", "3.02E3", "3.02E3"},
                {"-3.01E3", "-3.01E3", "-3.01E3", "3.02E3", "3.02E3", "3.02E3"}};
        verifyRounding(format, values, expected, roundingModes, descriptions);
        values = new double[]{0.0, -0.0};
        // The order of these expected values correspond to the order of roundingModes and the order of values.
        expected = new String[][]{
                {"0.00E0", "-0.00E0"},
                {"0.00E0", "-0.00E0"},
                {"0.00E0", "-0.00E0"},
                {"0.00E0", "-0.00E0"},
                {"0.00E0", "-0.00E0"},
                {"0.00E0", "-0.00E0"},
                {"0.00E0", "-0.00E0"}};
        verifyRounding(format, values, expected, roundingModes, descriptions);
        values = new double[]{1e25, 1e25 + 1e15, 1e25 - 1e15};
        // The order of these expected values correspond to the order of roundingModes and the order of values.
        expected = new String[][]{
                {"1.00E25", "1.01E25", "1.00E25"},
                {"1.00E25", "1.00E25", "9.99E24"},
                {"1.00E25", "1.00E25", "9.99E24"},
                {"1.00E25", "1.00E25", "1.00E25"},
                {"1.00E25", "1.00E25", "1.00E25"},
                {"1.00E25", "1.00E25", "1.00E25"},
                {"1.00E25", "1.01E25", "1.00E25"}};
        verifyRounding(format, values, expected, roundingModes, descriptions);
        values = new double[]{-1e25, -1e25 + 1e15, -1e25 - 1e15};
        // The order of these expected values correspond to the order of roundingModes and the order of values.
        expected = new String[][]{
                {"-1.00E25", "-9.99E24", "-1.00E25"},
                {"-1.00E25", "-9.99E24", "-1.00E25"},
                {"-1.00E25", "-1.00E25", "-1.01E25"},
                {"-1.00E25", "-1.00E25", "-1.00E25"},
                {"-1.00E25", "-1.00E25", "-1.00E25"},
                {"-1.00E25", "-1.00E25", "-1.00E25"},
                {"-1.00E25", "-1.00E25", "-1.01E25"}};
        verifyRounding(format, values, expected, roundingModes, descriptions);
        values = new double[]{1e-25, 1e-25 + 1e-35, 1e-25 - 1e-35};
        // The order of these expected values correspond to the order of roundingModes and the order of values.
        expected = new String[][]{
                {"1.00E-25", "1.01E-25", "1.00E-25"},
                {"1.00E-25", "1.00E-25", "9.99E-26"},
                {"1.00E-25", "1.00E-25", "9.99E-26"},
                {"1.00E-25", "1.00E-25", "1.00E-25"},
                {"1.00E-25", "1.00E-25", "1.00E-25"},
                {"1.00E-25", "1.00E-25", "1.00E-25"},
                {"1.00E-25", "1.01E-25", "1.00E-25"}};
        verifyRounding(format, values, expected, roundingModes, descriptions);
        values = new double[]{-1e-25, -1e-25 + 1e-35, -1e-25 - 1e-35};
        // The order of these expected values correspond to the order of roundingModes and the order of values.
        expected = new String[][]{
                {"-1.00E-25", "-9.99E-26", "-1.00E-25"},
                {"-1.00E-25", "-9.99E-26", "-1.00E-25"},
                {"-1.00E-25", "-1.00E-25", "-1.01E-25"},
                {"-1.00E-25", "-1.00E-25", "-1.00E-25"},
                {"-1.00E-25", "-1.00E-25", "-1.00E-25"},
                {"-1.00E-25", "-1.00E-25", "-1.00E-25"},
                {"-1.00E-25", "-1.00E-25", "-1.01E-25"}};
        verifyRounding(format, values, expected, roundingModes, descriptions);
    }

    private void verifyRounding(DecimalFormat format, double[] values, String[][] expected, int[] roundingModes,
            String[] descriptions) {
        for (int i = 0; i < roundingModes.length; i++) {
            format.setRoundingMode(roundingModes[i]);
            for (int j = 0; j < values.length; j++) {
                assertEquals(descriptions[i]+" " +values[j], expected[i][j], format.format(values[j]));
            }
        }
    }

    @Test
    public void Test10419RoundingWith0FractionDigits() {
        Object[][] data = new Object[][]{
                {BigDecimal.ROUND_CEILING, 1.488, "2"},
                {BigDecimal.ROUND_DOWN, 1.588, "1"},
                {BigDecimal.ROUND_FLOOR, 1.588, "1"},
                {BigDecimal.ROUND_HALF_DOWN, 1.5, "1"},
                {BigDecimal.ROUND_HALF_EVEN, 2.5, "2"},
                {BigDecimal.ROUND_HALF_UP, 2.5, "3"},
                {BigDecimal.ROUND_UP, 1.5, "2"},
        };
        NumberFormat nff = NumberFormat.getNumberInstance(ULocale.ENGLISH);
        nff.setMaximumFractionDigits(0);
        for (Object[] item : data) {
          nff.setRoundingMode(((Integer) item[0]).intValue());
          assertEquals("Test10419", item[2], nff.format(item[1]));
        }
    }

    @Test
    public void TestParseNegativeWithFaLocale() {
        DecimalFormat parser = (DecimalFormat) NumberFormat.getInstance(new ULocale("fa"));
        try {
            double value = parser.parse("-0,5").doubleValue();
            assertEquals("Expect -0.5", -0.5, value);
        } catch (ParseException e) {
            TestFmwk.errln("Parsing -0.5 should have succeeded.");
        }
    }

    @Test
    public void TestParseNegativeWithAlternativeMinusSign() {
        DecimalFormat parser = (DecimalFormat) NumberFormat.getInstance(new ULocale("en"));
        try {
            double value = parser.parse("\u208B0.5").doubleValue();
            assertEquals("Expect -0.5", -0.5, value);
        } catch (ParseException e) {
            TestFmwk.errln("Parsing -0.5 should have succeeded.");
        }
    }

    // Test various patterns
    @Test
    public void TestPatterns() {

        DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US);
        final String pat[]    = { "#.#", "#.", ".#", "#" };
        int pat_length = pat.length;
        final String newpat[] = { "0.#", "0.", "#.0", "0" };
        final String num[]    = { "0",   "0.", ".0", "0" };
        for (int i=0; i<pat_length; ++i)
        {
            DecimalFormat fmt = new DecimalFormat(pat[i], sym);
            String newp = fmt.toPattern();
            if (!newp.equals(newpat[i]))
                errln("FAIL: Pattern " + pat[i] + " should transmute to " + newpat[i] +
                        "; " + newp + " seen instead");

            String s = ((NumberFormat)fmt).format(0);
            if (!s.equals(num[i]))
            {
                errln("FAIL: Pattern " + pat[i] + " should format zero as " + num[i] +
                        "; " + s + " seen instead");
                logln("Min integer digits = " + fmt.getMinimumIntegerDigits());
            }
            // BigInteger 0 - ticket#4731
            s = ((NumberFormat)fmt).format(BigInteger.ZERO);
            if (!s.equals(num[i]))
            {
                errln("FAIL: Pattern " + pat[i] + " should format BigInteger zero as " + num[i] +
                        "; " + s + " seen instead");
                logln("Min integer digits = " + fmt.getMinimumIntegerDigits());
            }
        }
    }

    @Test
    public void Test20186_SpacesAroundSemicolon() {
        DecimalFormat df = new DecimalFormat("0.00 ; -0.00");
        expect2(df, 1, "1.00 ");
        expect2(df, -1, " -1.00");

        df = new DecimalFormat("0.00;");
        expect2(df, 1, "1.00");
        expect2(df, -1, "-1.00");

        df = new DecimalFormat("0.00;0.00");
        expect2(df, 1, "1.00");
        expect(df, -1, "1.00");  // parses as 1, not -1

        df = new DecimalFormat(" 0.00 ; -0.00 ");
        expect2(df, 1, " 1.00 ");
        expect2(df, -1, " -1.00 ");
    }

    // Test exponential pattern
    @Test
    public void TestExponential() {

        DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US);
        final String pat[] = { "0.####E0", "00.000E00", "##0.######E000", "0.###E0;[0.###E0]" };
        int pat_length = pat.length;

        double val[] = { 0.01234, 123456789, 1.23e300, -3.141592653e-271 };
        int val_length = val.length;
        final String valFormat[] = {
                // 0.####E0
                "1.234E-2", "1.2346E8", "1.23E300", "-3.1416E-271",
                // 00.000E00
                "12.340E-03", "12.346E07", "12.300E299", "-31.416E-272",
                // ##0.######E000
                "12.34E-003", "123.4568E006", "1.23E300", "-314.1593E-273",
                // 0.###E0;[0.###E0]
                "1.234E-2", "1.235E8", "1.23E300", "[3.142E-271]" };
        /*double valParse[] =
            {
                0.01234, 123460000, 1.23E300, -3.1416E-271,
                0.01234, 123460000, 1.23E300, -3.1416E-271,
                0.01234, 123456800, 1.23E300, -3.141593E-271,
                0.01234, 123500000, 1.23E300, -3.142E-271,
            };*/ //The variable is never used

        int lval[] = { 0, -1, 1, 123456789 };
        int lval_length = lval.length;
        final String lvalFormat[] = {
                // 0.####E0
                "0E0", "-1E0", "1E0", "1.2346E8",
                // 00.000E00
                "00.000E00", "-10.000E-01", "10.000E-01", "12.346E07",
                // ##0.######E000
                "0E000", "-1E000", "1E000", "123.4568E006",
                // 0.###E0;[0.###E0]
                "0E0", "[1E0]", "1E0", "1.235E8" };
        int lvalParse[] =
            {
                0, -1, 1, 123460000,
                0, -1, 1, 123460000,
                0, -1, 1, 123456800,
                0, -1, 1, 123500000,
            };
        int ival = 0, ilval = 0;
        for (int p = 0; p < pat_length; ++p) {
            DecimalFormat fmt = new DecimalFormat(pat[p], sym);
            logln("Pattern \"" + pat[p] + "\" -toPattern-> \"" + fmt.toPattern() + "\"");
            int v;
            for (v = 0; v < val_length; ++v) {
                String s;
                s = ((NumberFormat) fmt).format(val[v]);
                logln(" " + val[v] + " -format-> " + s);
                if (!s.equals(valFormat[v + ival]))
                    errln("FAIL: Expected " + valFormat[v + ival]);

                ParsePosition pos = new ParsePosition(0);
                double a = fmt.parse(s, pos).doubleValue();
                if (pos.getIndex() == s.length()) {
                    logln("  -parse-> " + Double.toString(a));
                    // Use epsilon comparison as necessary
                } else
                    errln("FAIL: Partial parse (" + pos.getIndex() + " chars) -> " + a);
            }
            for (v = 0; v < lval_length; ++v) {
                String s;
                s = ((NumberFormat) fmt).format(lval[v]);
                logln(" " + lval[v] + "L -format-> " + s);
                if (!s.equals(lvalFormat[v + ilval]))
                    errln("ERROR: Expected " + lvalFormat[v + ilval] + " Got: " + s);

                ParsePosition pos = new ParsePosition(0);
                long a = 0;
                Number A = fmt.parse(s, pos);
                if (A != null) {
                    a = A.longValue();
                    if (pos.getIndex() == s.length()) {
                        logln("  -parse-> " + a);
                        if (a != lvalParse[v + ilval])
                            errln("FAIL: Expected " + lvalParse[v + ilval]);
                    } else
                        errln("FAIL: Partial parse (" + pos.getIndex() + " chars) -> " + Long.toString(a));
                } else {
                    errln("Fail to parse the string: " + s);
                }
            }
            ival += val_length;
            ilval += lval_length;
        }
    }

    // Test the handling of quotes
    @Test
    public void TestQuotes() {

        StringBuffer pat;
        DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US);
        pat = new StringBuffer("a'fo''o'b#");
        DecimalFormat fmt = new DecimalFormat(pat.toString(), sym);
        String s = ((NumberFormat)fmt).format(123);
        logln("Pattern \"" + pat + "\"");
        logln(" Format 123 . " + s);
        if (!s.equals("afo'ob123"))
            errln("FAIL: Expected afo'ob123");

        s ="";
        pat = new StringBuffer("a''b#");
        fmt = new DecimalFormat(pat.toString(), sym);
        s = ((NumberFormat)fmt).format(123);
        logln("Pattern \"" + pat + "\"");
        logln(" Format 123 . " + s);
        if (!s.equals("a'b123"))
            errln("FAIL: Expected a'b123");
    }

    @Test
    public void TestParseCurrencyTrailingSymbol() {
        // see sun bug 4709840
        NumberFormat fmt = NumberFormat.getCurrencyInstance(Locale.GERMANY);
        float val = 12345.67f;
        String str = fmt.format(val);
        logln("val: " + val + " str: " + str);
        try {
            Number num = fmt.parse(str);
            logln("num: " + num);
        } catch (ParseException e) {
            errln("parse of '" + str + "' threw exception: " + e);
        }
    }

    /**
     * Test the handling of the currency symbol in patterns.
     **/
    @Test
    public void TestCurrencySign() {
        DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US);
        StringBuffer pat = new StringBuffer("");
        char currency = 0x00A4;
        // "\xA4#,##0.00;-\xA4#,##0.00"
        pat.append(currency).append("#,##0.00;-").append(currency).append("#,##0.00");
        DecimalFormat fmt = new DecimalFormat(pat.toString(), sym);
        String s = ((NumberFormat) fmt).format(1234.56);
        pat = new StringBuffer();
        logln("Pattern \"" + fmt.toPattern() + "\"");
        logln(" Format " + 1234.56 + " . " + s);
        assertEquals("symbol, pos", "$1,234.56", s);

        s = ((NumberFormat) fmt).format(-1234.56);
        logln(" Format " + Double.toString(-1234.56) + " . " + s);
        assertEquals("symbol, neg", "-$1,234.56", s);

        pat.setLength(0);
        // "\xA4\xA4 #,##0.00;\xA4\xA4 -#,##0.00"
        pat.append(currency).append(currency).append(" #,##0.00;").append(currency).append(currency).append(" -#,##0.00");
        fmt = new DecimalFormat(pat.toString(), sym);
        s = ((NumberFormat) fmt).format(1234.56);
        logln("Pattern \"" + fmt.toPattern() + "\"");
        logln(" Format " + Double.toString(1234.56) + " . " + s);
        assertEquals("name, pos", "USD 1,234.56", s);

        s = ((NumberFormat) fmt).format(-1234.56);
        logln(" Format " + Double.toString(-1234.56) + " . " + s);
        assertEquals("name, neg", "USD -1,234.56", s);
    }

    @Test
    public void TestSpaceParsing() {
        // the data are:
        // the string to be parsed, parsed position, parsed error index
        String[][] DATA = {
                {"$124", "4", "-1"},
                {"$124 $124", "4", "-1"},
                {"$124 ", "4", "-1"},
                {"$124  ", "4", "-1"},
                {"$ 124 ", "5", "-1"},
                {"$\u00A0124 ", "5", "-1"},
                {" $ 124 ", "6", "-1"},
                {"124$", "4", "-1"},
                {"124 $", "5", "-1"},
                {"$124\u200A", "4", "-1"},
                {"$\u200A124", "5", "-1"},
        };
        NumberFormat foo = NumberFormat.getCurrencyInstance();
        for (int i = 0; i < DATA.length; ++i) {
            ParsePosition parsePosition = new ParsePosition(0);
            String stringToBeParsed = DATA[i][0];
            int parsedPosition = Integer.parseInt(DATA[i][1]);
            int errorIndex = Integer.parseInt(DATA[i][2]);
            try {
                Number result = foo.parse(stringToBeParsed, parsePosition);
                if (parsePosition.getIndex() != parsedPosition ||
                        parsePosition.getErrorIndex() != errorIndex) {
                    errln("FAILED parse " + stringToBeParsed + "; parse position: " + parsePosition.getIndex() + "; error position: " + parsePosition.getErrorIndex());
                }
                if (parsePosition.getErrorIndex() == -1 &&
                        result.doubleValue() != 124) {
                    errln("FAILED parse " + stringToBeParsed + "; value " + result.doubleValue());
                }
            } catch (Exception e) {
                errln("FAILED " + e.toString());
            }
        }
    }

    @Test
    public void TestSpaceParsingStrict() {
        // All trailing grouping separators should be ignored in strict mode, not just the first.
        Object[][] cases = {
                {"123 ", 3, -1},
                {"123  ", 3, -1},
                {"123  ,", 3, -1},
                {"123,", 3, -1},
                {"123, ", 3, -1},
                {"123,,", 3, -1},
                {"123,, ", 3, -1},
                {"123,,456", 3, -1},
                {"123 ,", 3, -1},
                {"123, ", 3, -1},
                {"123, 456", 3, -1},
                {"123  456", 3, -1}
        };
        DecimalFormat df = new DecimalFormat("#,###");
        df.setParseStrict(true);
        for (Object[] cas : cases) {
            String input = (String) cas[0];
            int expectedIndex = (Integer) cas[1];
            int expectedErrorIndex = (Integer) cas[2];
            ParsePosition ppos = new ParsePosition(0);
            df.parse(input, ppos);
            assertEquals("Failed on index: '" + input + "'", expectedIndex, ppos.getIndex());
            assertEquals("Failed on error: '" + input + "'", expectedErrorIndex, ppos.getErrorIndex());
        }
    }

    @Test
    public void TestMultiCurrencySign() {
        String[][] DATA = {
                // the fields in the following test are:
                // locale,
                // currency pattern (with negative pattern),
                // currency number to be formatted,
                // currency format using currency symbol name, such as "$" for USD,
                // currency format using currency ISO name, such as "USD",
                // currency format using plural name, such as "US dollars".
                // for US locale
                {"en_US", "\u00A4#,##0.00;-\u00A4#,##0.00", "1234.56", "$1,234.56", "USD 1,234.56", "US dollars 1,234.56"},
                {"en_US", "\u00A4#,##0.00;-\u00A4#,##0.00", "-1234.56", "-$1,234.56", "-USD 1,234.56", "-US dollars 1,234.56"},
                {"en_US", "\u00A4#,##0.00;-\u00A4#,##0.00", "1", "$1.00", "USD 1.00", "US dollars 1.00"},
                // for CHINA locale
                {"zh_CN", "\u00A4#,##0.00;(\u00A4#,##0.00)", "1234.56", "\u00A51,234.56", "CNY 1,234.56", "\u4EBA\u6C11\u5E01 1,234.56"},
                {"zh_CN", "\u00A4#,##0.00;(\u00A4#,##0.00)", "-1234.56", "(\u00A51,234.56)", "(CNY 1,234.56)", "(\u4EBA\u6C11\u5E01 1,234.56)"},
                {"zh_CN", "\u00A4#,##0.00;(\u00A4#,##0.00)", "1", "\u00A51.00", "CNY 1.00", "\u4EBA\u6C11\u5E01 1.00"}
        };

        String doubleCurrencyStr = "\u00A4\u00A4";
        String tripleCurrencyStr = "\u00A4\u00A4\u00A4";

        for (int i=0; i<DATA.length; ++i) {
            String locale = DATA[i][0];
            String pat = DATA[i][1];
            Double numberToBeFormat = new Double(DATA[i][2]);
            DecimalFormatSymbols sym = new DecimalFormatSymbols(new ULocale(locale));
            for (int j=1; j<=3; ++j) {
                // j represents the number of currency sign in the pattern.
                if (j == 2) {
                    pat = pat.replaceAll("\u00A4", doubleCurrencyStr);
                } else if (j == 3) {
                    pat = pat.replaceAll("\u00A4\u00A4", tripleCurrencyStr);
                }
                DecimalFormat fmt = new DecimalFormat(pat, sym);
                String s = ((NumberFormat) fmt).format(numberToBeFormat);
                // DATA[i][3] is the currency format result using a
                // single currency sign.
                // DATA[i][4] is the currency format result using
                // double currency sign.
                // DATA[i][5] is the currency format result using
                // triple currency sign.
                // DATA[i][j+2] is the currency format result using
                // 'j' number of currency sign.
                String currencyFormatResult = DATA[i][2+j];
                if (!s.equals(currencyFormatResult)) {
                    errln("FAIL format: Expected " + currencyFormatResult + " but got " + s);
                }
                try {
                    // mix style parsing
                    for (int k=3; k<=4; ++k) {
                        // DATA[i][3] is the currency format result using a
                        // single currency sign.
                        // DATA[i][4] is the currency format result using
                        // double currency sign.
                        // DATA[i][5] is the currency format result using
                        // triple currency sign.
                        // ICU 59: long name parsing requires currency mode.
                        String oneCurrencyFormat = DATA[i][k];
                        if (fmt.parse(oneCurrencyFormat).doubleValue() !=
                                numberToBeFormat.doubleValue()) {
                            errln("FAILED parse " + oneCurrencyFormat);
                        }
                    }
                } catch (ParseException e) {
                    errln("FAILED, DecimalFormat parse currency: " + e.toString());
                }
            }
        }
    }

    @Test
    public void TestCurrencyFormatForMixParsing() {
        MeasureFormat curFmt = MeasureFormat.getCurrencyFormat(new ULocale("en_US"));
        String[] formats = {
                "$1,234.56",  // string to be parsed
                "USD1,234.56",
                "US dollars1,234.56",
                "1,234.56 US dollars"
        };
        try {
            for (int i = 0; i < formats.length; ++i) {
                String stringToBeParsed = formats[i];
                CurrencyAmount parsedVal = (CurrencyAmount)curFmt.parseObject(stringToBeParsed);
                Number val = parsedVal.getNumber();
                if (!val.equals(new BigDecimal("1234.56"))) {
                    errln("FAIL: getCurrencyFormat of default locale (en_US) failed roundtripping the number. val=" + val);
                }
                if (!parsedVal.getCurrency().equals(Currency.getInstance("USD"))) {
                    errln("FAIL: getCurrencyFormat of default locale (en_US) failed roundtripping the currency");
                }
            }
        } catch (ParseException e) {
            errln("parse FAILED: " + e.toString());
        }
    }


    /** Starting in ICU 62, strict mode is actually strict with currency formats. */
    @Test
    public void TestMismatchedCurrencyFormatFail() {
        DecimalFormat df = (DecimalFormat) NumberFormat.getCurrencyInstance(ULocale.ENGLISH);
        assertEquals("Test assumes that currency sign is at the beginning",
                "\u00A4#,##0.00",
                df.toPattern());
        // Should round-trip on the correct currency format:
        expect2(df, 1.23, "\u00A41.23");
        df.setCurrency(Currency.getInstance("EUR"));
        expect2(df, 1.23, "\u20AC1.23");
        // Should parse with currency in the wrong place in lenient mode
        df.setParseStrict(false);
        expect(df, "1.23\u20AC", 1.23);
        expectParseCurrency(df, Currency.getInstance("EUR"), "1.23\u20AC");
        // Should NOT parse with currency in the wrong place in STRICT mode
        df.setParseStrict(true);
        {
            ParsePosition ppos = new ParsePosition(0);
            df.parse("1.23\u20AC", ppos);
            assertEquals("Should fail to parse", 0, ppos.getIndex());
        }
        {
            ParsePosition ppos = new ParsePosition(0);
            df.parseCurrency("1.23\u20AC", ppos);
            assertEquals("Should fail to parse currency", 0, ppos.getIndex());
        }
    }

    @Test
    public void TestDecimalFormatCurrencyParse() {
        // Locale.US
        DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US);
        StringBuffer pat = new StringBuffer("");
        char currency = 0x00A4;
        // "\xA4#,##0.00;-\xA4#,##0.00"
        pat.append(currency).append(currency).append(currency).append("#,##0.00;-").append(currency).append(currency).append(currency).append("#,##0.00");
        DecimalFormat fmt = new DecimalFormat(pat.toString(), sym);
        String[][] DATA = {
                // the data are:
                // string to be parsed, the parsed result (number)
                {"$1.00", "1"},
                {"USD1.00", "1"},
                {"1.00 US dollar", "1"},
                {"$1,234.56", "1234.56"},
                {"USD1,234.56", "1234.56"},
                {"1,234.56 US dollar", "1234.56"},
        };
        try {
            for (int i = 0; i < DATA.length; ++i) {
                String stringToBeParsed = DATA[i][0];
                double parsedResult = Double.parseDouble(DATA[i][1]);
                Number num = fmt.parse(stringToBeParsed);
                if (num.doubleValue() != parsedResult) {
                    errln("FAIL parse: Expected " + parsedResult);
                }
            }
        } catch (ParseException e) {
            errln("FAILED, DecimalFormat parse currency: " + e.toString());
        }
    }

    /**
     * Test localized currency patterns.
     */
    @Test
    public void TestCurrency() {
        String[] DATA = {
                "fr_CA", "1,50\u00a0$",
                "de_DE", "1,50\u00a0\u20AC",
                "de_DE@currency=DEM", "1,50\u00a0DM",
                "fr_FR", "1,50\u00a0\u20AC",
                "fr_FR@currency=FRF", "1,50\u00a0F",
        };

        for (int i=0; i<DATA.length; i+=2) {
            Locale locale = new Locale(DATA[i]);
            NumberFormat fmt = NumberFormat.getCurrencyInstance(locale);
            String s = fmt.format(1.50);
            if (s.equals(DATA[i+1])) {
                logln("Ok: 1.50 x " + locale + " => " + s);
            } else {
                logln("FAIL: 1.50 x " + locale + " => " + s +
                        ", expected " + DATA[i+1]);
            }
        }

        // format currency with CurrencyAmount
        for (int i=0; i<DATA.length; i+=2) {
            Locale locale = new Locale(DATA[i]);

            Currency curr = Currency.getInstance(locale);
            logln("\nName of the currency is: " + curr.getName(locale, Currency.LONG_NAME, new boolean[] {false}));
            CurrencyAmount cAmt = new CurrencyAmount(1.5, curr);
            logln("CurrencyAmount object's hashCode is: " + cAmt.hashCode()); //cover hashCode

            NumberFormat fmt = NumberFormat.getCurrencyInstance(locale);
            String sCurr = fmt.format(cAmt);
            if (sCurr.equals(DATA[i+1])) {
                logln("Ok: 1.50 x " + locale + " => " + sCurr);
            } else {
                errln("FAIL: 1.50 x " + locale + " => " + sCurr +
                        ", expected " + DATA[i+1]);
            }
        }

        //Cover MeasureFormat.getCurrencyFormat()
        ULocale save = ULocale.getDefault();
        ULocale.setDefault(ULocale.US);
        MeasureFormat curFmt = MeasureFormat.getCurrencyFormat();
        String strBuf = curFmt.format(new CurrencyAmount(new Float(1234.56), Currency.getInstance("USD")));

        try {
            CurrencyAmount parsedVal = (CurrencyAmount)curFmt.parseObject(strBuf);
            Number val = parsedVal.getNumber();
            if (!val.equals(new BigDecimal("1234.56"))) {
                errln("FAIL: getCurrencyFormat of default locale (en_US) failed roundtripping the number. val=" + val);
            }
            if (!parsedVal.getCurrency().equals(Currency.getInstance("USD"))) {
                errln("FAIL: getCurrencyFormat of default locale (en_US) failed roundtripping the currency");
            }
        }
        catch (ParseException e) {
            errln("FAIL: " + e.getMessage());
        }
        ULocale.setDefault(save);
    }

    @Test
    public void TestJavaCurrencyConversion() {
        java.util.Currency gbpJava = java.util.Currency.getInstance("GBP");
        Currency gbpIcu = Currency.getInstance("GBP");
        assertEquals("ICU should equal API value", gbpIcu, Currency.fromJavaCurrency(gbpJava));
        assertEquals("Java should equal API value", gbpJava, gbpIcu.toJavaCurrency());
        // Test CurrencyAmount constructors
        CurrencyAmount ca1 = new CurrencyAmount(123.45, gbpJava);
        CurrencyAmount ca2 = new CurrencyAmount(123.45, gbpIcu);
        assertEquals("CurrencyAmount from both Double constructors should be equal", ca1, ca2);
        // Coverage for the Number constructor
        ca1 = new CurrencyAmount(new BigDecimal("543.21"), gbpJava);
        ca2 = new CurrencyAmount(new BigDecimal("543.21"), gbpIcu);
        assertEquals("CurrencyAmount from both Number constructors should be equal", ca1, ca2);
    }

    @Test
    public void TestCurrencyIsoPluralFormat() {
        String[][] DATA = {
                // the data are:
                // locale,
                // currency amount to be formatted,
                // currency ISO code to be formatted,
                // format result using CURRENCYSTYLE,
                // format result using ISOCURRENCYSTYLE,
                // format result using PLURALCURRENCYSTYLE,
                {"en_US", "1", "USD", "$1.00", "USD 1.00", "1.00 US dollars"},
                {"en_US", "1234.56", "USD", "$1,234.56", "USD 1,234.56", "1,234.56 US dollars"},
                {"en_US", "-1234.56", "USD", "-$1,234.56", "-USD 1,234.56", "-1,234.56 US dollars"},
                {"zh_CN", "1", "USD", "US$1.00", "USD 1.00", "1.00 美元"},
                {"zh_CN", "1234.56", "USD", "US$1,234.56", "USD 1,234.56", "1,234.56 美元"},
                {"zh_CN", "1", "CNY", "¥1.00", "CNY 1.00", "1.00 人民币"},
                {"zh_CN", "1234.56", "CNY", "¥1,234.56", "CNY 1,234.56", "1,234.56 人民币"},
                {"ru_RU", "1", "RUB", "1,00 \u20BD", "1,00 RUB", "1,00 российского рубля"},
                {"ru_RU", "2", "RUB", "2,00 \u20BD", "2,00 RUB", "2,00 российского рубля"},
                {"ru_RU", "5", "RUB", "5,00 \u20BD", "5,00 RUB", "5,00 российского рубля"},
                // test locale without currency information
                {"root", "-1.23", "USD", "-US$ 1.23", "-USD 1.23", "-1.23 USD"},
                {"root@numbers=latn", "-1.23", "USD", "-US$ 1.23", "-USD 1.23", "-1.23 USD"}, // ensure that the root locale is still used with modifiers
                {"root@numbers=arab", "-1.23", "USD", "\u061C-\u0661\u066B\u0662\u0663\u00A0US$", "\u061C-\u0661\u066B\u0662\u0663\u00A0USD", "\u061C-\u0661\u066B\u0662\u0663 USD"}, // ensure that the root locale is still used with modifiers
                {"es_AR", "1", "INR", "INR\u00A01,00", "INR\u00A01,00", "1,00 rupia india"},
                {"ar_EG", "1", "USD", "١٫٠٠\u00A0US$", "١٫٠٠\u00A0USD", "١٫٠٠ دولار أمريكي"},
        };

        for (int i=0; i<DATA.length; ++i) {
            for (int k = NumberFormat.CURRENCYSTYLE;
                    k <= NumberFormat.PLURALCURRENCYSTYLE;
                    ++k) {
                // k represents currency format style.
                if ( k != NumberFormat.CURRENCYSTYLE &&
                        k != NumberFormat.ISOCURRENCYSTYLE &&
                        k != NumberFormat.PLURALCURRENCYSTYLE ) {
                    continue;
                }
                String localeString = DATA[i][0];
                Double numberToBeFormat = new Double(DATA[i][1]);
                String currencyISOCode = DATA[i][2];
                ULocale locale = new ULocale(localeString);
                NumberFormat numFmt = NumberFormat.getInstance(locale, k);
                numFmt.setCurrency(Currency.getInstance(currencyISOCode));
                String strBuf = numFmt.format(numberToBeFormat);
                int resultDataIndex = k-1;
                if ( k == NumberFormat.CURRENCYSTYLE ) {
                    resultDataIndex = k+2;
                }
                // DATA[i][resultDataIndex] is the currency format result
                // using 'k' currency style.
                String formatResult = DATA[i][resultDataIndex];
                if (!strBuf.equals(formatResult)) {
                    errln("FAIL: localeID: " + localeString + ", expected(" + formatResult.length() + "): \"" + formatResult + "\", actual(" + strBuf.length() + "): \"" + strBuf + "\"");
                }
                // test parsing, and test parsing for all currency formats.
                for (int j = 3; j < 6; ++j) {
                    // DATA[i][3] is the currency format result using
                    // CURRENCYSTYLE formatter.
                    // DATA[i][4] is the currency format result using
                    // ISOCURRENCYSTYLE formatter.
                    // DATA[i][5] is the currency format result using
                    // PLURALCURRENCYSTYLE formatter.
                    String oneCurrencyFormatResult = DATA[i][j];
                    CurrencyAmount val = numFmt.parseCurrency(oneCurrencyFormatResult, null);
                    if (val.getNumber().doubleValue() != numberToBeFormat.doubleValue()) {
                        errln("FAIL: getCurrencyFormat of locale " + localeString + " failed roundtripping the number. val=" + val + "; expected: " + numberToBeFormat);
                    }
                }
            }
        }
    }


    @Test
    public void TestMiscCurrencyParsing() {
        String[][] DATA = {
                // each has: string to be parsed, parsed position, error position
                {"1.00 ", "4", "-1", "0", "4"},
                {"1.00 UAE dirha", "4", "-1", "0", "4"},
                {"1.00 us dollar", "14", "-1", "14", "-1"},
                {"1.00 US DOLLAR", "14", "-1", "14", "-1"},
                {"1.00 usd", "8", "-1", "8", "-1"},
                {"1.00 USD", "8", "-1", "8", "-1"},
        };
        ULocale locale = new ULocale("en_US");
        for (int i=0; i<DATA.length; ++i) {
            String stringToBeParsed = DATA[i][0];
            int parsedPosition = Integer.parseInt(DATA[i][1]);
            int errorIndex = Integer.parseInt(DATA[i][2]);
            int currParsedPosition = Integer.parseInt(DATA[i][3]);
            int currErrorIndex = Integer.parseInt(DATA[i][4]);
            NumberFormat numFmt = NumberFormat.getInstance(locale, NumberFormat.CURRENCYSTYLE);
            ParsePosition parsePosition = new ParsePosition(0);
            Number val = numFmt.parse(stringToBeParsed, parsePosition);
            if (parsePosition.getIndex() != parsedPosition ||
                    parsePosition.getErrorIndex() != errorIndex) {
                errln("FAIL: parse failed on case "+i+". expected position: " + parsedPosition +"; actual: " + parsePosition.getIndex());
                errln("FAIL: parse failed on case "+i+". expected error position: " + errorIndex + "; actual: " + parsePosition.getErrorIndex());
            }
            if (parsePosition.getErrorIndex() == -1 &&
                    val.doubleValue() != 1.00) {
                errln("FAIL: parse failed. expected 1.00, actual:" + val);
            }
            parsePosition = new ParsePosition(0);
            CurrencyAmount amt = numFmt.parseCurrency(stringToBeParsed, parsePosition);
            if (parsePosition.getIndex() != currParsedPosition ||
                    parsePosition.getErrorIndex() != currErrorIndex) {
                errln("FAIL: parseCurrency failed on case "+i+". expected error position: " + currErrorIndex + "; actual: " + parsePosition.getErrorIndex());
                errln("FAIL: parseCurrency failed on case "+i+". expected position: " + currParsedPosition +"; actual: " + parsePosition.getIndex());
            }
            if (parsePosition.getErrorIndex() == -1 &&
                    amt.getNumber().doubleValue() != 1.00) {
                errln("FAIL: parseCurrency failed. expected 1.00, actual:" + val);
            }
        }
    }

    @Test
    public void TestParseCurrency() {
        class ParseCurrencyItem {
            private final String localeString;
            private final String descrip;
            private final String currStr;
            private final int    doubExpectPos;
            private final int    doubExpectVal;
            private final int    curExpectPos;
            private final int    curExpectVal;
            private final String curExpectCurr;

            ParseCurrencyItem(String locStr, String desc, String curr, int doubExPos, int doubExVal, int curExPos, int curExVal, String curExCurr) {
                localeString  = locStr;
                descrip       = desc;
                currStr       = curr;
                doubExpectPos  = doubExPos;
                doubExpectVal  = doubExVal;
                curExpectPos  = curExPos;
                curExpectVal  = curExVal;
                curExpectCurr = curExCurr;
            }
            public String getLocaleString()  { return localeString; }
            public String getDescrip()       { return descrip; }
            public String getCurrStr()       { return currStr; }
            public int    getDoubExpectPos()  { return doubExpectPos; }
            public int    getDoubExpectVal()  { return doubExpectVal; }
            public int    getCurExpectPos()  { return curExpectPos; }
            public int    getCurExpectVal()  { return curExpectVal; }
            public String getCurExpectCurr() { return curExpectCurr; }
        }
        // Note: In cases where the number occurs before the currency sign, non-currency mode will parse the number
        // and stop when it reaches the currency symbol.
        final ParseCurrencyItem[] parseCurrencyItems = {
                new ParseCurrencyItem( "en_US", "dollars2", "$2.00",            5,  2,  5,  2,  "USD" ),
                new ParseCurrencyItem( "en_US", "dollars4", "$4",               2,  4,  2,  4,  "USD" ),
                new ParseCurrencyItem( "en_US", "dollars9", "9\u00A0$",         3,  9,  3,  9,  "USD" ),
                new ParseCurrencyItem( "en_US", "pounds3",  "\u00A33.00",       0,  0,  5,  3,  "GBP" ),
                new ParseCurrencyItem( "en_US", "pounds5",  "\u00A35",          0,  0,  2,  5,  "GBP" ),
                new ParseCurrencyItem( "en_US", "pounds7",  "7\u00A0\u00A3",    1,  7,  3,  7,  "GBP" ),
                new ParseCurrencyItem( "en_US", "euros8",   "\u20AC8",          0,  0,  2,  8,  "EUR" ),

                new ParseCurrencyItem( "en_GB", "pounds3",  "\u00A33.00",       5,  3,  5,  3,  "GBP" ),
                new ParseCurrencyItem( "en_GB", "pounds5",  "\u00A35",          2,  5,  2,  5,  "GBP" ),
                new ParseCurrencyItem( "en_GB", "pounds7",  "7\u00A0\u00A3",    3,  7,  3,  7,  "GBP" ),
                new ParseCurrencyItem( "en_GB", "euros4",   "4,00\u00A0\u20AC", 4,400,  6,400,  "EUR" ),
                new ParseCurrencyItem( "en_GB", "euros6",   "6\u00A0\u20AC",    1,  6,  3,  6,  "EUR" ),
                new ParseCurrencyItem( "en_GB", "euros8",   "\u20AC8",          0,  0,  2,  8,  "EUR" ),
                new ParseCurrencyItem( "en_GB", "dollars4", "US$4",             0,  0,  4,  4,  "USD" ),

                new ParseCurrencyItem( "fr_FR", "euros4",   "4,00\u00A0\u20AC", 6,  4,  6,  4,  "EUR" ),
                new ParseCurrencyItem( "fr_FR", "euros6",   "6\u00A0\u20AC",    3,  6,  3,  6,  "EUR" ),
                new ParseCurrencyItem( "fr_FR", "euros8",   "\u20AC8",          2,  8,  2,  8,  "EUR" ),
                new ParseCurrencyItem( "fr_FR", "dollars2", "$2.00",            0,  0,  0,  0,  ""    ),
                new ParseCurrencyItem( "fr_FR", "dollars4", "$4",               0,  0,  0,  0,  ""    ),
        };
        for (ParseCurrencyItem item: parseCurrencyItems) {
            String localeString = item.getLocaleString();
            ULocale uloc = new ULocale(localeString);
            NumberFormat fmt = null;
            try {
                fmt = NumberFormat.getCurrencyInstance(uloc);
            } catch (Exception e) {
                errln("NumberFormat.getCurrencyInstance fails for locale " + localeString);
                continue;
            }
            String currStr = item.getCurrStr();
            ParsePosition parsePos = new ParsePosition(0);

            Number numVal = fmt.parse(currStr, parsePos);
            if ( parsePos.getIndex() != item.getDoubExpectPos() || (numVal != null && numVal.intValue() != item.getDoubExpectVal()) ) {
                if (numVal != null) {
                    errln("NumberFormat.getCurrencyInstance parse " + localeString + "/" + item.getDescrip() +
                            ", expect pos/val " + item.getDoubExpectPos() + "/" + item.getDoubExpectVal() +
                            ", get " + parsePos.getIndex() + "/" + numVal.intValue() );
                } else {
                    errln("NumberFormat.getCurrencyInstance parse " + localeString + "/" + item.getDescrip() +
                            ", expect pos/val " + item.getDoubExpectPos() + "/" + item.getDoubExpectVal() +
                            ", get " + parsePos.getIndex() + "/(NULL)" );
                }
            }

            parsePos.setIndex(0);
            int curExpectPos = item.getCurExpectPos();
            CurrencyAmount currAmt = fmt.parseCurrency(currStr, parsePos);
            if ( parsePos.getIndex() != curExpectPos || (currAmt != null && (currAmt.getNumber().intValue() != item.getCurExpectVal() ||
                    currAmt.getCurrency().getCurrencyCode().compareTo(item.getCurExpectCurr()) != 0)) ) {
                if (currAmt != null) {
                    errln("NumberFormat.getCurrencyInstance parseCurrency " + localeString + "/" + item.getDescrip() +
                            ", expect pos/val/curr " + curExpectPos + "/" + item.getCurExpectVal() + "/" + item.getCurExpectCurr() +
                            ", get " + parsePos.getIndex() + "/" + currAmt.getNumber().intValue() + "/" + currAmt.getCurrency().getCurrencyCode() );
                } else {
                    errln("NumberFormat.getCurrencyInstance parseCurrency " + localeString + "/" + item.getDescrip() +
                            ", expect pos/val/curr " + curExpectPos + "/" + item.getCurExpectVal() + "/" + item.getCurExpectCurr() +
                            ", get " + parsePos.getIndex() + "/(NULL)" );
                }
            }
        }
    }

    @Test
    public void TestParseCurrencyWithWhitespace() {
        DecimalFormat df = new DecimalFormat("#,##0.00 ¤¤");
        ParsePosition ppos = new ParsePosition(0);
        df.parseCurrency("1.00 us denmark", ppos);
        assertEquals("Expected to fail on 'us denmark' string", 4, ppos.getErrorIndex());
    }

    @Test
    public void TestParseCurrPatternWithDecStyle() {
        String currpat = "¤#,##0.00";
        String parsetxt = "x0y$";
        DecimalFormat decfmt = (DecimalFormat)NumberFormat.getInstance(new ULocale("en_US"), NumberFormat.NUMBERSTYLE);
        decfmt.applyPattern(currpat);
        ParsePosition ppos = new ParsePosition(0);
        Number value = decfmt.parse(parsetxt, ppos);
        if (ppos.getIndex() != 0) {
            errln("DecimalFormat.parse expected to fail but got ppos " + ppos.getIndex() + ", value " + value);
        }
    }

    /**
     * Test the Currency object handling, new as of ICU 2.2.
     */
    @Test
    public void TestCurrencyObject() {
        NumberFormat fmt =
                NumberFormat.getCurrencyInstance(Locale.US);

        expectCurrency(fmt, null, 1234.56, "$1,234.56");

        expectCurrency(fmt, Currency.getInstance(Locale.FRANCE),
                1234.56, "\u20AC1,234.56"); // Euro

        expectCurrency(fmt, Currency.getInstance(Locale.JAPAN),
                1234.56, "\u00A51,235"); // Yen

        expectCurrency(fmt, Currency.getInstance(new Locale("fr", "CH", "")),
                1234.56, "CHF 1,234.56"); // no more 0.05 rounding here, see cldrbug 5548

        expectCurrency(fmt, Currency.getInstance(Locale.US),
                1234.56, "$1,234.56");

        fmt = NumberFormat.getCurrencyInstance(Locale.FRANCE);

        expectCurrency(fmt, null, 1234.56, "1\u202F234,56 \u20AC");

        expectCurrency(fmt, Currency.getInstance(Locale.JAPAN),
                1234.56, "1\u202F235 JPY"); // Yen

        expectCurrency(fmt, Currency.getInstance(new Locale("fr", "CH", "")),
                1234.56, "1\u202F234,56 CHF"); // no more rounding here, see cldrbug 5548

        expectCurrency(fmt, Currency.getInstance(Locale.US),
                1234.56, "1\u202F234,56 $US");

        expectCurrency(fmt, Currency.getInstance(Locale.FRANCE),
                1234.56, "1\u202F234,56 \u20AC"); // Euro
    }

    @Test
    public void TestCompatibleCurrencies() {
        NumberFormat fmt =
                NumberFormat.getCurrencyInstance(Locale.US);
        expectParseCurrency(fmt, Currency.getInstance(Locale.JAPAN), "\u00A51,235"); // Yen half-width
        expectParseCurrency(fmt, Currency.getInstance(Locale.JAPAN), "\uFFE51,235"); // Yen full-wdith
    }

    @Test
    public void TestCurrencyPatterns() {
        int i;
        Random rnd = new Random(2017);
        Locale[] locs = NumberFormat.getAvailableLocales();
        for (i=0; i<locs.length; ++i) {
            if (rnd.nextDouble() < 0.9) {
                // Check a random subset for speed:
                // Otherwise, this test takes a large fraction of the entire time.
                continue;
            }
            NumberFormat nf = NumberFormat.getCurrencyInstance(locs[i]);
            // Make sure currency formats do not have a variable number
            // of fraction digits
            int min = nf.getMinimumFractionDigits();
            int max = nf.getMaximumFractionDigits();
            if (min != max) {
                String a = nf.format(1.0);
                String b = nf.format(1.125);
                errln("FAIL: " + locs[i] +
                        " min fraction digits != max fraction digits; "+
                        "x 1.0 => " + a +
                        "; x 1.125 => " + b);
            }

            // Make sure EURO currency formats have exactly 2 fraction digits
            if (nf instanceof DecimalFormat) {
                Currency curr = ((DecimalFormat) nf).getCurrency();
                if (curr != null && "EUR".equals(curr.getCurrencyCode())) {
                    if (min != 2 || max != 2) {
                        String a = nf.format(1.0);
                        errln("FAIL: " + locs[i] +
                                " is a EURO format but it does not have 2 fraction digits; "+
                                "x 1.0 => " +
                                a);
                    }
                }
            }
        }
    }

    /**
     * Do rudimentary testing of parsing.
     */
    @Test
    public void TestParse() {
        String arg = "0.0";
        DecimalFormat format = new DecimalFormat("00");
        double aNumber = 0l;
        try {
            aNumber = format.parse(arg).doubleValue();
        } catch (ParseException e) {
            System.out.println(e);
        }
        logln("parse(" + arg + ") = " + aNumber);
    }

    /**
     * Test proper rounding by the format method.
     */
    @Test
    public void TestRounding487() {

        NumberFormat nf = NumberFormat.getInstance();
        roundingTest(nf, 0.00159999, 4, "0.0016");
        roundingTest(nf, 0.00995, 4, "0.01");

        roundingTest(nf, 12.3995, 3, "12.4");

        roundingTest(nf, 12.4999, 0, "12");
        roundingTest(nf, - 19.5, 0, "-20");

    }

    /**
     * Test the functioning of the secondary grouping value.
     */
    @Test
    public void TestSecondaryGrouping() {

        DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
        DecimalFormat f = new DecimalFormat("#,##,###", US);

        expect(f, 123456789L, "12,34,56,789");
        expectPat(f, "#,##,##0");
        f.applyPattern("#,###");

        f.setSecondaryGroupingSize(4);
        expect(f, 123456789L, "12,3456,789");
        expectPat(f, "#,####,##0");
        NumberFormat g = NumberFormat.getInstance(new Locale("hi", "IN"));

        String out = "";
        long l = 1876543210L;
        out = g.format(l);

        // expect "1,87,65,43,210", but with Hindi digits
        //         01234567890123
        boolean ok = true;
        if (out.length() != 14) {
            ok = false;
        } else {
            for (int i = 0; i < out.length(); ++i) {
                boolean expectGroup = false;
                switch (i) {
                case 1 :
                case 4 :
                case 7 :
                case 10 :
                    expectGroup = true;
                    break;
                }
                // Later -- fix this to get the actual grouping
                // character from the resource bundle.
                boolean isGroup = (out.charAt(i) == 0x002C);
                if (isGroup != expectGroup) {
                    ok = false;
                    break;
                }
            }
        }
        if (!ok) {
            errln("FAIL  Expected "+ l + " x hi_IN . \"1,87,65,43,210\" (with Hindi digits), got \""
                    + out + "\"");
        } else {
            logln("Ok    " + l + " x hi_IN . \"" + out + "\"");
        }
    }

    /*
     * Internal test utility.
     */
    private void roundingTest(NumberFormat nf, double x, int maxFractionDigits, final String expected) {
        nf.setMaximumFractionDigits(maxFractionDigits);
        String out = nf.format(x);
        logln(x + " formats with " + maxFractionDigits + " fractional digits to " + out);
        if (!out.equals(expected))
            errln("FAIL: Expected " + expected);
    }

    /**
     * Upgrade to alphaWorks
     */
    @Test
    public void TestExponent() {
        DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
        DecimalFormat fmt1 = new DecimalFormat("0.###E0", US);
        DecimalFormat fmt2 = new DecimalFormat("0.###E+0", US);
        int n = 1234;
        expect2(fmt1, n, "1.234E3");
        expect2(fmt2, n, "1.234E+3");
        expect(fmt1, "1.234E+3", n); // Either format should parse "E+3"

    }

    /**
     * Upgrade to alphaWorks
     */
    @Test
    public void TestScientific() {

        DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);

        // Test pattern round-trip
        final String PAT[] = { "#E0", "0.####E0", "00.000E00", "##0.####E000", "0.###E0;[0.###E0]" };
        int PAT_length = PAT.length;
        int DIGITS[] = {
                // min int, max int, min frac, max frac
                0, 1, 0, 0, // "#E0"
                1, 1, 0, 4, // "0.####E0"
                2, 2, 3, 3, // "00.000E00"
                1, 3, 0, 4, // "##0.####E000"
                1, 1, 0, 3, // "0.###E0;[0.###E0]"
        };
        for (int i = 0; i < PAT_length; ++i) {
            String pat = PAT[i];
            DecimalFormat df = new DecimalFormat(pat, US);
            String pat2 = df.toPattern();
            if (pat.equals(pat2)) {
                logln("Ok   Pattern rt \"" + pat + "\" . \"" + pat2 + "\"");
            } else {
                errln("FAIL Pattern rt \"" + pat + "\" . \"" + pat2 + "\"");
            }
            // Make sure digit counts match what we expect
            if (i == 0) continue; // outputs to 1,1,0,0 since at least one min digit is required.
            if (df.getMinimumIntegerDigits() != DIGITS[4 * i]
                    || df.getMaximumIntegerDigits() != DIGITS[4 * i + 1]
                            || df.getMinimumFractionDigits() != DIGITS[4 * i + 2]
                                    || df.getMaximumFractionDigits() != DIGITS[4 * i + 3]) {
                errln("FAIL \""+ pat+ "\" min/max int; min/max frac = "
                        + df.getMinimumIntegerDigits() + "/"
                        + df.getMaximumIntegerDigits() + ";"
                        + df.getMinimumFractionDigits() + "/"
                        + df.getMaximumFractionDigits() + ", expect "
                        + DIGITS[4 * i] + "/"
                        + DIGITS[4 * i + 1] + ";"
                        + DIGITS[4 * i + 2] + "/"
                        + DIGITS[4 * i + 3]);
            }
        }

        expect2(new DecimalFormat("#E0", US), 12345.0, "1.2345E4");
        expect(new DecimalFormat("0E0", US), 12345.0, "1E4");

        // pattern of NumberFormat.getScientificInstance(Locale.US) = "0.######E0" not "#E0"
        // so result = 1.234568E4 not 1.2345678901E4
        //when the pattern problem is finalized, delete comment mark'//'
        //of the following code
        expect2(NumberFormat.getScientificInstance(Locale.US), 12345.678901, "1.2345678901E4");
        logln("Testing NumberFormat.getScientificInstance(ULocale) ...");
        expect2(NumberFormat.getScientificInstance(ULocale.US), 12345.678901, "1.2345678901E4");

        expect(new DecimalFormat("##0.###E0", US), 12345.0, "12.34E3");
        expect(new DecimalFormat("##0.###E0", US), 12345.00001, "12.35E3");
        expect2(new DecimalFormat("##0.####E0", US), 12345, "12.345E3");

        // pattern of NumberFormat.getScientificInstance(Locale.US) = "0.######E0" not "#E0"
        // so result = 1.234568E4 not 1.2345678901E4
        expect2(NumberFormat.getScientificInstance(Locale.FRANCE), 12345.678901, "1,2345678901E4");
        logln("Testing NumberFormat.getScientificInstance(ULocale) ...");
        expect2(NumberFormat.getScientificInstance(ULocale.FRANCE), 12345.678901, "1,2345678901E4");

        expect(new DecimalFormat("##0.####E0", US), 789.12345e-9, "789.12E-9");
        expect2(new DecimalFormat("##0.####E0", US), 780.e-9, "780E-9");
        expect(new DecimalFormat(".###E0", US), 45678.0, ".457E5");
        expect2(new DecimalFormat(".###E0", US), 0, ".0E0");
        /*
        expect(new DecimalFormat[] { new DecimalFormat("#E0", US),
                                     new DecimalFormat("##E0", US),
                                     new DecimalFormat("####E0", US),
                                     new DecimalFormat("0E0", US),
                                     new DecimalFormat("00E0", US),
                                     new DecimalFormat("000E0", US),
                                   },
               new Long(45678000),
               new String[] { "4.5678E7",
                              "45.678E6",
                              "4567.8E4",
                              "5E7",
                              "46E6",
                              "457E5",
                            }
               );
        !
        ! Unroll this test into individual tests below...
        !
         */
        expect2(new DecimalFormat("#E0", US), 45678000, "4.5678E7");
        expect2(new DecimalFormat("##E0", US), 45678000, "45.678E6");
        expect2(new DecimalFormat("####E0", US), 45678000, "4567.8E4");
        expect(new DecimalFormat("0E0", US), 45678000, "5E7");
        expect(new DecimalFormat("00E0", US), 45678000, "46E6");
        expect(new DecimalFormat("000E0", US), 45678000, "457E5");
        /*
        expect(new DecimalFormat("###E0", US, status),
               new Object[] { new Double(0.0000123), "12.3E-6",
                              new Double(0.000123), "123E-6",
                              new Double(0.00123), "1.23E-3",
                              new Double(0.0123), "12.3E-3",
                              new Double(0.123), "123E-3",
                              new Double(1.23), "1.23E0",
                              new Double(12.3), "12.3E0",
                              new Double(123), "123E0",
                              new Double(1230), "1.23E3",
                             });
        !
        ! Unroll this test into individual tests below...
        !
         */
        expect2(new DecimalFormat("###E0", US), 0.0000123, "12.3E-6");
        expect2(new DecimalFormat("###E0", US), 0.000123, "123E-6");
        expect2(new DecimalFormat("###E0", US), 0.00123, "1.23E-3");
        expect2(new DecimalFormat("###E0", US), 0.0123, "12.3E-3");
        expect2(new DecimalFormat("###E0", US), 0.123, "123E-3");
        expect2(new DecimalFormat("###E0", US), 1.23, "1.23E0");
        expect2(new DecimalFormat("###E0", US), 12.3, "12.3E0");
        expect2(new DecimalFormat("###E0", US), 123.0, "123E0");
        expect2(new DecimalFormat("###E0", US), 1230.0, "1.23E3");
        /*
        expect(new DecimalFormat("0.#E+00", US, status),
               new Object[] { new Double(0.00012), "1.2E-04",
                              new Long(12000),     "1.2E+04",
                             });
        !
        ! Unroll this test into individual tests below...
        !
         */
        expect2(new DecimalFormat("0.#E+00", US), 0.00012, "1.2E-04");
        expect2(new DecimalFormat("0.#E+00", US), 12000, "1.2E+04");
    }

    /**
     * Upgrade to alphaWorks
     */
    @Test
    public void TestPad() {

        DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
        expect2(new DecimalFormat("*^##.##", US), 0, "^^^^0");
        expect2(new DecimalFormat("*^##.##", US), -1.3, "^-1.3");
        expect2(
                new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US),
                0,
                "0.0E0______ g-m/s^2");
        expect(
                new DecimalFormat("##0.0####E0*_ 'g-m/s^2'", US),
                1.0 / 3,
                "333.333E-3_ g-m/s^2");
        expect2(new DecimalFormat("##0.0####*_ 'g-m/s^2'", US), 0, "0.0______ g-m/s^2");
        expect(
                new DecimalFormat("##0.0####*_ 'g-m/s^2'", US),
                1.0 / 3,
                "0.33333__ g-m/s^2");

        // Test padding before a sign
        final String formatStr = "*x#,###,###,##0.0#;*x(###,###,##0.0#)";
        expect2(new DecimalFormat(formatStr, US), -10, "xxxxxxxxxx(10.0)");
        expect2(new DecimalFormat(formatStr, US), -1000, "xxxxxxx(1,000.0)");
        expect2(new DecimalFormat(formatStr, US), -1000000, "xxx(1,000,000.0)");
        expect2(new DecimalFormat(formatStr, US), -100.37, "xxxxxxxx(100.37)");
        expect2(new DecimalFormat(formatStr, US), -10456.37, "xxxxx(10,456.37)");
        expect2(new DecimalFormat(formatStr, US), -1120456.37, "xx(1,120,456.37)");
        expect2(new DecimalFormat(formatStr, US), -112045600.37, "(112,045,600.37)");
        expect2(new DecimalFormat(formatStr, US), -1252045600.37, "(1,252,045,600.37)");

        expect2(new DecimalFormat(formatStr, US), 10, "xxxxxxxxxxxx10.0");
        expect2(new DecimalFormat(formatStr, US), 1000, "xxxxxxxxx1,000.0");
        expect2(new DecimalFormat(formatStr, US), 1000000, "xxxxx1,000,000.0");
        expect2(new DecimalFormat(formatStr, US), 100.37, "xxxxxxxxxx100.37");
        expect2(new DecimalFormat(formatStr, US), 10456.37, "xxxxxxx10,456.37");
        expect2(new DecimalFormat(formatStr, US), 1120456.37, "xxxx1,120,456.37");
        expect2(new DecimalFormat(formatStr, US), 112045600.37, "xx112,045,600.37");
        expect2(new DecimalFormat(formatStr, US), 10252045600.37, "10,252,045,600.37");

        // Test padding between a sign and a number
        final String formatStr2 = "#,###,###,##0.0#*x;(###,###,##0.0#*x)";
        expect2(new DecimalFormat(formatStr2, US), -10, "(10.0xxxxxxxxxx)");
        expect2(new DecimalFormat(formatStr2, US), -1000, "(1,000.0xxxxxxx)");
        expect2(new DecimalFormat(formatStr2, US), -1000000, "(1,000,000.0xxx)");
        expect2(new DecimalFormat(formatStr2, US), -100.37, "(100.37xxxxxxxx)");
        expect2(new DecimalFormat(formatStr2, US), -10456.37, "(10,456.37xxxxx)");
        expect2(new DecimalFormat(formatStr2, US), -1120456.37, "(1,120,456.37xx)");
        expect2(new DecimalFormat(formatStr2, US), -112045600.37, "(112,045,600.37)");
        expect2(new DecimalFormat(formatStr2, US), -1252045600.37, "(1,252,045,600.37)");

        expect2(new DecimalFormat(formatStr2, US), 10, "10.0xxxxxxxxxxxx");
        expect2(new DecimalFormat(formatStr2, US), 1000, "1,000.0xxxxxxxxx");
        expect2(new DecimalFormat(formatStr2, US), 1000000, "1,000,000.0xxxxx");
        expect2(new DecimalFormat(formatStr2, US), 100.37, "100.37xxxxxxxxxx");
        expect2(new DecimalFormat(formatStr2, US), 10456.37, "10,456.37xxxxxxx");
        expect2(new DecimalFormat(formatStr2, US), 1120456.37, "1,120,456.37xxxx");
        expect2(new DecimalFormat(formatStr2, US), 112045600.37, "112,045,600.37xx");
        expect2(new DecimalFormat(formatStr2, US), 10252045600.37, "10,252,045,600.37");

        //testing the setPadCharacter(UnicodeString) and getPadCharacterString()
        DecimalFormat fmt = new DecimalFormat("#", US);
        char padString = 'P';
        fmt.setPadCharacter(padString);
        expectPad(fmt, "*P##.##", DecimalFormat.PAD_BEFORE_PREFIX, 5, padString);
        fmt.setPadCharacter('^');
        expectPad(fmt, "*^#", DecimalFormat.PAD_BEFORE_PREFIX, 1, '^');
        //commented untill implementation is complete
        /*  fmt.setPadCharacter((UnicodeString)"^^^");
          expectPad(fmt, "*^^^#", DecimalFormat.kPadBeforePrefix, 3, (UnicodeString)"^^^");
          padString.remove();
          padString.append((UChar)0x0061);
          padString.append((UChar)0x0302);
          fmt.setPadCharacter(padString);
          UChar patternChars[]={0x002a, 0x0061, 0x0302, 0x0061, 0x0302, 0x0023, 0x0000};
          UnicodeString pattern(patternChars);
          expectPad(fmt, pattern , DecimalFormat.kPadBeforePrefix, 4, padString);
         */

        // Test multi-char padding sequence specified via pattern
        expect2(new DecimalFormat("*'😃'####.00", US), 1.1, "😃😃😃1.10");
    }

    @Test
    public void TestIgnorePadding() {
        DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US);
        DecimalFormat fmt = new DecimalFormat("", dfs);
        fmt.setGroupingUsed(false);
        fmt.setFormatWidth(0);
        fmt.setPadCharacter('*');
        fmt.setPadPosition(0);
        fmt.setMinimumIntegerDigits(0);
        fmt.setMaximumIntegerDigits(8);
        fmt.setMinimumFractionDigits(0);
        fmt.setMaximumFractionDigits(0);
        String pattern = fmt.toPattern();
        if (pattern.startsWith("*")) {
            errln("ERROR toPattern result should ignore padding but get \"" + pattern + "\"");
        }
        fmt.applyPattern(pattern);
        String format = fmt.format(24);
        if (!format.equals("24")) {
             errln("ERROR format result expect 24 but get \"" + format + "\"");
       }
    }

    /**
     * Upgrade to alphaWorks
     */
    @Test
    public void TestPatterns2() {
        DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
        DecimalFormat fmt = new DecimalFormat("#", US);

        char hat = 0x005E; /*^*/

        expectPad(fmt, "*^#", DecimalFormat.PAD_BEFORE_PREFIX, 1, hat);
        expectPad(fmt, "$*^#", DecimalFormat.PAD_AFTER_PREFIX, 2, hat);
        expectPad(fmt, "#*^", DecimalFormat.PAD_BEFORE_SUFFIX, 1, hat);
        expectPad(fmt, "#$*^", DecimalFormat.PAD_AFTER_SUFFIX, 2, hat);
        expectPad(fmt, "$*^$#", -1);
        expectPad(fmt, "#$*^$", -1);
        expectPad(fmt, "'pre'#,##0*x'post'", DecimalFormat.PAD_BEFORE_SUFFIX, 12, (char) 0x0078 /*x*/);
        expectPad(fmt, "''#0*x", DecimalFormat.PAD_BEFORE_SUFFIX, 3, (char) 0x0078 /*x*/);
        expectPad(fmt, "'I''ll'*a###.##", DecimalFormat.PAD_AFTER_PREFIX, 10, (char) 0x0061 /*a*/);

        fmt.applyPattern("AA#,##0.00ZZ");
        fmt.setPadCharacter(hat);

        fmt.setFormatWidth(10);

        fmt.setPadPosition(DecimalFormat.PAD_BEFORE_PREFIX);
        expectPat(fmt, "*^AA#,##0.00ZZ");

        fmt.setPadPosition(DecimalFormat.PAD_BEFORE_SUFFIX);
        expectPat(fmt, "AA#,##0.00*^ZZ");

        fmt.setPadPosition(DecimalFormat.PAD_AFTER_SUFFIX);
        expectPat(fmt, "AA#,##0.00ZZ*^");

        //            12  3456789012
        String exp = "AA*^#,##0.00ZZ";
        fmt.setFormatWidth(12);
        fmt.setPadPosition(DecimalFormat.PAD_AFTER_PREFIX);
        expectPat(fmt, exp);

        fmt.setFormatWidth(13);
        //              12  34567890123
        expectPat(fmt, "AA*^##,##0.00ZZ");

        fmt.setFormatWidth(14);
        //              12  345678901234
        expectPat(fmt, "AA*^###,##0.00ZZ");

        fmt.setFormatWidth(15);
        //              12  3456789012345
        expectPat(fmt, "AA*^####,##0.00ZZ"); // This is the interesting case

        // The new implementation produces "AA*^#####,##0.00ZZ", which is functionally equivalent
        // to what the old implementation produced, "AA*^#,###,##0.00ZZ"
        fmt.setFormatWidth(16);
        //              12  34567890123456
        //expectPat(fmt, "AA*^#,###,##0.00ZZ");
        expectPat(fmt, "AA*^#####,##0.00ZZ");
    }

    @Test
    public void TestRegistration() {
        final ULocale SRC_LOC = ULocale.FRANCE;
        final ULocale SWAP_LOC = ULocale.US;

        class TestFactory extends SimpleNumberFormatFactory {
            NumberFormat currencyStyle;

            TestFactory() {
                super(SRC_LOC, true);
                currencyStyle = NumberFormat.getIntegerInstance(SWAP_LOC);
            }

            @Override
            public NumberFormat createFormat(ULocale loc, int formatType) {
                if (formatType == FORMAT_CURRENCY) {
                    return currencyStyle;
                }
                return null;
            }
        }

        NumberFormat f0 = NumberFormat.getIntegerInstance(SWAP_LOC);
        NumberFormat f1 = NumberFormat.getIntegerInstance(SRC_LOC);
        NumberFormat f2 = NumberFormat.getCurrencyInstance(SRC_LOC);
        Object key = NumberFormat.registerFactory(new TestFactory());
        NumberFormat f3 = NumberFormat.getCurrencyInstance(SRC_LOC);
        NumberFormat f4 = NumberFormat.getIntegerInstance(SRC_LOC);
        NumberFormat.unregister(key); // restore for other tests
        NumberFormat f5 = NumberFormat.getCurrencyInstance(SRC_LOC);

        float n = 1234.567f;
        logln("f0 swap int: " + f0.format(n));
        logln("f1 src int: " + f1.format(n));
        logln("f2 src cur: " + f2.format(n));
        logln("f3 reg cur: " + f3.format(n));
        logln("f4 reg int: " + f4.format(n));
        logln("f5 unreg cur: " + f5.format(n));

        if (!f3.format(n).equals(f0.format(n))) {
            errln("registered service did not match");
        }
        if (!f4.format(n).equals(f1.format(n))) {
            errln("registered service did not inherit");
        }
        if (!f5.format(n).equals(f2.format(n))) {
            errln("unregistered service did not match original");
        }
    }

    @Test
    public void TestScientific2() {
        // jb 2552
        DecimalFormat fmt = (DecimalFormat)NumberFormat.getCurrencyInstance();
        Number num = new Double(12.34);
        expect(fmt, num, "$12.34");
        fmt.setScientificNotation(true);
        expect(fmt, num, "$1.23E1");
        fmt.setScientificNotation(false);
        expect(fmt, num, "$12.34");
    }

    @Test
    public void TestScientificGrouping() {
        // jb 2552
        DecimalFormat fmt = new DecimalFormat("###.##E0");
        expect(fmt, .01234, "12.3E-3");
        expect(fmt, .1234, "123E-3");
        expect(fmt, 1.234, "1.23E0");
        expect(fmt, 12.34, "12.3E0");
        expect(fmt, 123.4, "123E0");
        expect(fmt, 1234, "1.23E3");
    }

    // additional coverage tests

    // sigh, can't have static inner classes, why not?

    static final class PI extends Number {
        /**
         * For serialization
         */
        private static final long serialVersionUID = -305601227915602172L;

        private PI() {}
        @Override
        public int intValue() { return (int)Math.PI; }
        @Override
        public long longValue() { return (long)Math.PI; }
        @Override
        public float  floatValue() { return (float)Math.PI; }
        @Override
        public double doubleValue() { return Math.PI; }
        @Override
        public byte byteValue() { return (byte)Math.PI; }
        @Override
        public short shortValue() { return (short)Math.PI; }

        public static final Number INSTANCE = new PI();
    }

    @Test
    public void TestCoverage() {
        NumberFormat fmt = NumberFormat.getNumberInstance(); // default locale
        logln(fmt.format(new BigInteger("1234567890987654321234567890987654321", 10)));

        fmt = NumberFormat.getScientificInstance(); // default locale

        logln(fmt.format(PI.INSTANCE));

        try {
            logln(fmt.format("12345"));
            errln("numberformat of string did not throw exception");
        }
        catch (Exception e) {
            logln("PASS: numberformat of string failed as expected");
        }

        int hash = fmt.hashCode();
        logln("hash code " + hash);

        logln("compare to string returns: " + fmt.equals(""));

        // For ICU 2.6 - alan
        DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
        DecimalFormat df = new DecimalFormat("'*&'' '\u00A4' ''&*' #,##0.00", US);
        df.setCurrency(Currency.getInstance("INR"));
        expect2(df, 1.0, "*&' \u20B9 '&* 1.00");
        expect2(df, -2.0, "-*&' \u20B9 '&* 2.00");
        df.applyPattern("#,##0.00 '*&'' '\u00A4' ''&*'");
        expect2(df, 2.0, "2.00 *&' \u20B9 '&*");
        expect2(df, -1.0, "-1.00 *&' \u20B9 '&*");

        java.math.BigDecimal r;

        r = df.getRoundingIncrement();
        if (r != null) {
            errln("FAIL: rounding = " + r + ", expect null");
        }

        if (df.isScientificNotation()) {
            errln("FAIL: isScientificNotation = true, expect false");
        }

        // Create a new instance to flush out currency info
        df = new DecimalFormat("0.00000", US);
        df.setScientificNotation(true);
        if (!df.isScientificNotation()) {
            errln("FAIL: isScientificNotation = false, expect true");
        }
        df.setMinimumExponentDigits((byte)2);
        if (df.getMinimumExponentDigits() != 2) {
            errln("FAIL: getMinimumExponentDigits = " +
                    df.getMinimumExponentDigits() + ", expect 2");
        }
        df.setExponentSignAlwaysShown(true);
        if (!df.isExponentSignAlwaysShown()) {
            errln("FAIL: isExponentSignAlwaysShown = false, expect true");
        }
        df.setSecondaryGroupingSize(0);
        if (df.getSecondaryGroupingSize() != 0) {
            errln("FAIL: getSecondaryGroupingSize = " +
                    df.getSecondaryGroupingSize() + ", expect 0");
        }
        expect2(df, 3.14159, "3.14159E+00");

        // DecimalFormatSymbols#getInstance
        DecimalFormatSymbols decsym1 = DecimalFormatSymbols.getInstance();
        DecimalFormatSymbols decsym2 = new DecimalFormatSymbols();
        if (!decsym1.equals(decsym2)) {
            errln("FAIL: DecimalFormatSymbols returned by getInstance()" +
                    "does not match new DecimalFormatSymbols().");
        }
        decsym1 = DecimalFormatSymbols.getInstance(Locale.JAPAN);
        decsym2 = DecimalFormatSymbols.getInstance(ULocale.JAPAN);
        if (!decsym1.equals(decsym2)) {
            errln("FAIL: DecimalFormatSymbols returned by getInstance(Locale.JAPAN)" +
                    "does not match the one returned by getInstance(ULocale.JAPAN).");
        }

        // DecimalFormatSymbols#getAvailableLocales/#getAvailableULocales
        Locale[] allLocales = DecimalFormatSymbols.getAvailableLocales();
        if (allLocales.length == 0) {
            errln("FAIL: Got a empty list for DecimalFormatSymbols.getAvailableLocales");
        } else {
            logln("PASS: " + allLocales.length +
                    " available locales returned by DecimalFormatSymbols.getAvailableLocales");
        }
        ULocale[] allULocales = DecimalFormatSymbols.getAvailableULocales();
        if (allULocales.length == 0) {
            errln("FAIL: Got a empty list for DecimalFormatSymbols.getAvailableLocales");
        } else {
            logln("PASS: " + allULocales.length +
                    " available locales returned by DecimalFormatSymbols.getAvailableULocales");
        }
    }

    @Test
    public void TestLocalizedPatternSymbolCoverage() {
        String[] standardPatterns = { "#,##0.05+%;#,##0.05-%", "* @@@E0‰" };
        String[] localizedPatterns = { "▰⁖▰▰໐⁘໐໕†⁜⁙▰⁖▰▰໐⁘໐໕‡⁜", "⁂ ⁕⁕⁕⁑⁑໐‱" };

        DecimalFormatSymbols dfs = new DecimalFormatSymbols();
        dfs.setGroupingSeparator('⁖');
        dfs.setDecimalSeparator('⁘');
        dfs.setPatternSeparator('⁙');
        dfs.setDigit('▰');
        dfs.setZeroDigit('໐');
        dfs.setSignificantDigit('⁕');
        dfs.setPlusSign('†');
        dfs.setMinusSign('‡');
        dfs.setPercent('⁜');
        dfs.setPerMill('‱');
        dfs.setExponentSeparator("⁑⁑"); // tests multi-char sequence
        dfs.setPadEscape('⁂');

        for (int i=0; i<2; i++) {
            String standardPattern = standardPatterns[i];
            String localizedPattern = localizedPatterns[i];

            DecimalFormat df1 = new DecimalFormat("#", dfs);
            df1.applyPattern(standardPattern);
            DecimalFormat df2 = new DecimalFormat("#", dfs);
            df2.applyLocalizedPattern(localizedPattern);
            assertEquals("DecimalFormat instances should be equal",
                    df1, df2);
            assertEquals("toPattern should match on localizedPattern instance",
                    standardPattern, df2.toPattern());
            assertEquals("toLocalizedPattern should match on standardPattern instance",
                    localizedPattern, df1.toLocalizedPattern());
        }
    }

    @Test
    public void TestParseEmpty(){
        String parsetxt = "";
        NumberFormat numfmt = NumberFormat.getInstance(new ULocale("en_US"), NumberFormat.NUMBERSTYLE);
        ParsePosition ppos = new ParsePosition(0);
        Number value = null;
        try {
            value = numfmt.parse(parsetxt, ppos);
            if (value==null) {
                logln("NumberFormat.parse empty string succeeds (no exception) with null return as expected, ppos " + ppos.getIndex());
            } else {
                errln("NumberFormat.parse empty string succeeds (no exception) but returns non-null value " + value + ", ppos " + ppos.getIndex());
            }
        } catch (IllegalArgumentException e){
            errln("NumberFormat.parse empty string throws IllegalArgumentException");
        }
     }

    @Test
    public void TestParseNull() throws ParseException {
        DecimalFormat df = new DecimalFormat();
        try {
            df.parse(null);
            fail("df.parse(null) didn't throw an exception");
        } catch (IllegalArgumentException e){}
        try {
            df.parse(null, null);
            fail("df.parse(null) didn't throw an exception");
        } catch (IllegalArgumentException e){}
        try {
            df.parseCurrency(null, null);
            fail("df.parse(null) didn't throw an exception");
        } catch (IllegalArgumentException e){}
    }

    @Test
    public void TestWhiteSpaceParsing() {
        DecimalFormatSymbols US = new DecimalFormatSymbols(Locale.US);
        DecimalFormat fmt = new DecimalFormat("a  b#0c  ", US);
        int n = 1234;
        expect(fmt, "a b1234c ", n);
        expect(fmt, "a   b1234c   ", n);
        expect(fmt, "ab1234", n);

        fmt.applyPattern("a b #");
        expect(fmt, "ab1234", n);
        expect(fmt, "ab  1234", n);
        expect(fmt, "a b1234", n);
        expect(fmt, "a   b1234", n);
        expect(fmt, " a b 1234", n);

        // Horizontal whitespace is allowed, but not vertical whitespace.
        expect(fmt, "\ta\u00A0b\u20001234", n);
        expect(fmt, "a   \u200A    b1234", n);
        expectParseException(fmt, "\nab1234", n);
        expectParseException(fmt, "a    \n   b1234", n);
        expectParseException(fmt, "a    \u0085   b1234", n);
        expectParseException(fmt, "a    \u2028   b1234", n);

        // Test all characters in the UTS 18 "blank" set stated in the API docstring.
        UnicodeSet blanks = new UnicodeSet("[[:Zs:][\\u0009]]").freeze();
        for (String space : blanks) {
            String str = "a " + space + " b1234c  ";
            expect(fmt, str, n);
        }

        // Arbitrary whitespace is not accepted in strict mode.
        fmt.setParseStrict(true);
        for (String space : blanks) {
            String str = "a " + space + " b1234c  ";
            expectParseException(fmt, str, n);
        }

        // Test default ignorable characters.  These should work in both lenient and strict.
        UnicodeSet defaultIgnorables = new UnicodeSet("[[:Bidi_Control:]]").freeze();
        fmt.setParseStrict(false);
        for (String ignorable : defaultIgnorables) {
            String str = "a b " + ignorable + "1234c  ";
            expect(fmt, str, n);
        }
        fmt.setParseStrict(true);
        for (String ignorable : defaultIgnorables) {
            String str = "a b " + ignorable + "1234c  ";
            expect(fmt, str, n);
        }

        // Test that other whitespace characters do not work
        fmt.setParseStrict(false);
        UnicodeSet otherWhitespace = new UnicodeSet("[[:whitespace:]]").removeAll(blanks).freeze();
        for (String space : otherWhitespace) {
            String str = "a  " + space + "  b1234";
            expectParseException(fmt, str, n);
        }
    }

    /**
     * Test currencies whose display name is a ChoiceFormat.
     */
    @Test
    public void TestComplexCurrency() {
        //  CLDR No Longer uses complex currency symbols.
        //  Skipping this test.
        //        Locale loc = new Locale("kn", "IN", "");
        //        NumberFormat fmt = NumberFormat.getCurrencyInstance(loc);

        //        expect2(fmt, 1.0, "Re.\u00a01.00");
        //        expect(fmt, 1.001, "Re.\u00a01.00"); // tricky
        //        expect2(fmt, 12345678.0, "Rs.\u00a01,23,45,678.00");
        //        expect2(fmt, 0.5, "Rs.\u00a00.50");
        //        expect2(fmt, -1.0, "-Re.\u00a01.00");
        //        expect2(fmt, -10.0, "-Rs.\u00a010.00");
    }

    @Test
    public void TestCurrencyKeyword() {
        ULocale locale = new ULocale("th_TH@currency=QQQ");
        NumberFormat format = NumberFormat.getCurrencyInstance(locale);
        String result = format.format(12.34f);
        if (!"QQQ 12.34".equals(result)) {
            errln("got unexpected currency: " + result);
        }
    }

    /**
     * Test alternate numbering systems
     */
    @Test
    public void TestNumberingSystems() {
        class TestNumberingSystemItem {
            private final String localeName;
            private final double value;
            private final boolean isRBNF;
            private final String expectedResult;

            TestNumberingSystemItem(String loc, double val, boolean rbnf, String exp) {
                localeName  = loc;
                value = val;
                isRBNF = rbnf;
                expectedResult = exp;
            }
        }

        final TestNumberingSystemItem[] DATA = {
                new TestNumberingSystemItem( "en_US@numbers=thai",        1234.567, false, "\u0e51,\u0e52\u0e53\u0e54.\u0e55\u0e56\u0e57" ),
                new TestNumberingSystemItem( "en_US@numbers=thai",        1234.567, false, "\u0E51,\u0E52\u0E53\u0E54.\u0E55\u0E56\u0E57" ),
                new TestNumberingSystemItem( "en_US@numbers=hebr",        5678.0,   true,  "\u05D4\u05F3\u05EA\u05E8\u05E2\u05F4\u05D7" ),
                new TestNumberingSystemItem( "en_US@numbers=arabext",     1234.567, false, "\u06F1\u066c\u06F2\u06F3\u06F4\u066b\u06F5\u06F6\u06F7" ),
                new TestNumberingSystemItem( "de_DE@numbers=foobar",      1234.567, false, "1.234,567" ),
                new TestNumberingSystemItem( "ar_EG",                     1234.567, false, "\u0661\u066c\u0662\u0663\u0664\u066b\u0665\u0666\u0667" ),
                new TestNumberingSystemItem( "th_TH@numbers=traditional", 1234.567, false, "\u0E51,\u0E52\u0E53\u0E54.\u0E55\u0E56\u0E57" ), // fall back to native per TR35
                new TestNumberingSystemItem( "ar_MA",                     1234.567, false, "1.234,567" ),
                new TestNumberingSystemItem( "en_US@numbers=hanidec",     1234.567, false, "\u4e00,\u4e8c\u4e09\u56db.\u4e94\u516d\u4e03" ),
                new TestNumberingSystemItem( "ta_IN@numbers=native",      1234.567, false, "\u0BE7,\u0BE8\u0BE9\u0BEA.\u0BEB\u0BEC\u0BED" ),
                new TestNumberingSystemItem( "ta_IN@numbers=traditional", 1235.0,   true,  "\u0BF2\u0BE8\u0BF1\u0BE9\u0BF0\u0BEB" ),
                new TestNumberingSystemItem( "ta_IN@numbers=finance",     1234.567, false, "1,234.567" ), // fall back to default per TR35
                new TestNumberingSystemItem( "zh_TW@numbers=native",      1234.567, false, "\u4e00,\u4e8c\u4e09\u56db.\u4e94\u516d\u4e03" ),
                new TestNumberingSystemItem( "zh_TW@numbers=traditional", 1234.567, true,  "\u4E00\u5343\u4E8C\u767E\u4E09\u5341\u56DB\u9EDE\u4E94\u516D\u4E03" ),
                new TestNumberingSystemItem( "zh_TW@numbers=finance",     1234.567, true,  "\u58F9\u4EDF\u8CB3\u4F70\u53C3\u62FE\u8086\u9EDE\u4F0D\u9678\u67D2" ),
                new TestNumberingSystemItem( "en_US@numbers=mathsanb",    1234.567, false,  "𝟭,𝟮𝟯𝟰.𝟱𝟲𝟳" ), // ticket #13286
        };


        for (TestNumberingSystemItem item : DATA) {
            ULocale loc = new ULocale(item.localeName);
            NumberFormat fmt = NumberFormat.getInstance(loc);
            if (item.isRBNF) {
                expect3(fmt,item.value,item.expectedResult);
            } else {
                expect2(fmt,item.value,item.expectedResult);
            }
        }
    }

    // Coverage tests for methods not being called otherwise.
    @Test
    public void TestNumberingSystemCoverage() {
        // Test getAvaliableNames
        String[] availableNames = NumberingSystem.getAvailableNames();
        if (availableNames == null || availableNames.length <= 0) {
            errln("ERROR: NumberingSystem.getAvailableNames() returned a null or empty array.");
        } else {
            // Check for alphabetical order
            for (int i=0; i<availableNames.length-1; i++) {
                assertTrue("Names should be in alphabetical order",
                        availableNames[i].compareTo(availableNames[i+1]) < 0);
            }

            boolean latnFound = false;
            for (String name : availableNames){
                assertNotEquals("should not throw and should not be null",
                        null, NumberingSystem.getInstanceByName(name));
                if ("latn".equals(name)) {
                    latnFound = true;
                    break;
                }
            }

            if (!latnFound) {
                errln("ERROR: 'latn' numbering system not found on NumberingSystem.getAvailableNames().");
            }
        }

        assertEquals("Non-existing numbering system should return null",
                null, NumberingSystem.getInstanceByName("dummy"));

        // Test NumberingSystem.getInstance()
        NumberingSystem ns1 = NumberingSystem.getInstance();
        if (ns1 == null || ns1.isAlgorithmic()) {
            errln("ERROR: NumberingSystem.getInstance() returned a null or invalid NumberingSystem");
        }

        // Test NumberingSystem.getInstance(int,boolean,String)
        /* Parameters used: the ones used in the default constructor
         * radix = 10;
         * algorithmic = false;
         * desc = "0123456789";
         */
        NumberingSystem ns2 = NumberingSystem.getInstance(10, false, "0123456789");
        if (ns2 == null || ns2.isAlgorithmic()) {
            errln("ERROR: NumberingSystem.getInstance(int,boolean,String) returned a null or invalid NumberingSystem");
        }

        // Test NumberingSystem.getInstance(Locale)
        NumberingSystem ns3 = NumberingSystem.getInstance(Locale.ENGLISH);
        if (ns3 == null || ns3.isAlgorithmic()) {
            errln("ERROR: NumberingSystem.getInstance(Locale) returned a null or invalid NumberingSystem");
        }
    }

    @Test
    public void Test6816() {
        Currency cur1 = Currency.getInstance(new Locale("und", "PH"));

        NumberFormat nfmt = NumberFormat.getCurrencyInstance(new Locale("und", "PH"));
        DecimalFormatSymbols decsym = ((DecimalFormat)nfmt).getDecimalFormatSymbols();
        Currency cur2 = decsym.getCurrency();

        if ( !cur1.getCurrencyCode().equals("PHP") || !cur2.getCurrencyCode().equals("PHP")) {
            errln("FAIL: Currencies should match PHP: cur1 = "+cur1.getCurrencyCode()+"; cur2 = "+cur2.getCurrencyCode());
        }

    }

    @Test
    public void TestThreadedFormat() {

        class FormatTask implements Runnable {
            DecimalFormat fmt;
            StringBuffer buf;
            boolean inc;
            float num;

            FormatTask(DecimalFormat fmt, int index) {
                this.fmt = fmt;
                this.buf = new StringBuffer();
                this.inc = (index & 0x1) == 0;
                this.num = inc ? 0 : 10000;
            }

            @Override
            public void run() {
                if (inc) {
                    while (num < 10000) {
                        buf.append(fmt.format(num) + "\n");
                        num += 3.14159;
                    }
                } else {
                    while (num > 0) {
                        buf.append(fmt.format(num) + "\n");
                        num -= 3.14159;
                    }
                }
            }

            String result() {
                return buf.toString();
            }
        }

        DecimalFormat fmt = new DecimalFormat("0.####");
        FormatTask[] tasks = new FormatTask[8];
        for (int i = 0; i < tasks.length; ++i) {
            tasks[i] = new FormatTask(fmt, i);
        }

        TestUtil.runUntilDone(tasks);

        for (int i = 2; i < tasks.length; i++) {
            String str1 = tasks[i].result();
            String str2 = tasks[i-2].result();
            if (!str1.equals(str2)) {
                System.out.println("mismatch at " + i);
                System.out.println(str1);
                System.out.println(str2);
                errln("decimal format thread mismatch");

                break;
            }
            str1 = str2;
        }
    }

    @Test
    public void TestPerMill() {
        DecimalFormat fmt = new DecimalFormat("###.###\u2030");
        assertEquals("0.4857 x ###.###\u2030",
                "485.7\u2030", fmt.format(0.4857));

        DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.ENGLISH);
        sym.setPerMill('m');
        DecimalFormat fmt2 = new DecimalFormat("", sym);
        fmt2.applyLocalizedPattern("###.###m");
        assertEquals("0.4857 x ###.###m",
                "485.7m", fmt2.format(0.4857));
    }

    @Test
    public void TestIllegalPatterns() {
        // Test cases:
        // Prefix with "-:" for illegal patterns
        // Prefix with "+:" for legal patterns
        String DATA[] = {
                // Unquoted special characters in the suffix are illegal
                "-:000.000|###",
                "+:000.000'|###'",
        };
        for (int i=0; i<DATA.length; ++i) {
            String pat=DATA[i];
            boolean valid = pat.charAt(0) == '+';
            pat = pat.substring(2);
            Exception e = null;
            try {
                // locale doesn't matter here
                new DecimalFormat(pat);
            } catch (IllegalArgumentException e1) {
                e = e1;
            } catch (IndexOutOfBoundsException e1) {
                e = e1;
            }
            String msg = (e==null) ? "success" : e.getMessage();
            if ((e==null) == valid) {
                logln("Ok: pattern \"" + pat + "\": " + msg);
            } else {
                errln("FAIL: pattern \"" + pat + "\" should have " +
                        (valid?"succeeded":"failed") + "; got " + msg);
            }
        }
    }

    /**
     * Parse a CurrencyAmount using the given NumberFormat, with
     * the 'delim' character separating the number and the currency.
     */
    private static CurrencyAmount parseCurrencyAmount(String str, NumberFormat fmt,
            char delim)
                    throws ParseException {
        int i = str.indexOf(delim);
        return new CurrencyAmount(fmt.parse(str.substring(0,i)),
                Currency.getInstance(str.substring(i+1)));
    }

    /**
     * Return an integer representing the next token from this
     * iterator.  The integer will be an index into the given list, or
     * -1 if there are no more tokens, or -2 if the token is not on
     * the list.
     */
    private static int keywordIndex(String tok) {
        for (int i=0; i<KEYWORDS.length; ++i) {
            if (tok.equals(KEYWORDS[i])) {
                return i;
            }
        }
        return -1;
    }

    private static final String KEYWORDS[] = {
        /*0*/ "ref=", // <reference pattern to parse numbers>
        /*1*/ "loc=", // <locale for formats>
        /*2*/ "f:",   // <pattern or '-'> <number> <exp. string>
        /*3*/ "fp:",  // <pattern or '-'> <number> <exp. string> <exp. number>
        /*4*/ "rt:",  // <pattern or '-'> <(exp.) number> <(exp.) string>
        /*5*/ "p:",   // <pattern or '-'> <string> <exp. number>
        /*6*/ "perr:", // <pattern or '-'> <invalid string>
        /*7*/ "pat:", // <pattern or '-'> <exp. toPattern or '-' or 'err'>
        /*8*/ "fpc:", // <loc or '-'> <curr.amt> <exp. string> <exp. curr.amt>
        /*9*/ "strict=", // true or false
    };

    @SuppressWarnings("resource")  // InputStream is will be closed by the ResourceReader.
    @Test
    public void TestCases() {
        String caseFileName = "NumberFormatTestCases.txt";
        java.io.InputStream is = NumberFormatTest.class.getResourceAsStream(caseFileName);

        ResourceReader reader = new ResourceReader(is, caseFileName, "utf-8");
        TokenIterator tokens = new TokenIterator(reader);

        Locale loc = new Locale("en", "US", "");
        DecimalFormat ref = null, fmt = null;
        MeasureFormat mfmt = null;
        String pat = null, str = null, mloc = null;
        boolean strict = false;

        try {
            for (;;) {
                String tok = tokens.next();
                if (tok == null) {
                    break;
                }
                String where = "(" + tokens.getLineNumber() + ") ";
                int cmd = keywordIndex(tok);
                switch (cmd) {
                case 0:
                    // ref= <reference pattern>
                    ref = new DecimalFormat(tokens.next(),
                            new DecimalFormatSymbols(Locale.US));
                    ref.setParseStrict(strict);
                    logln("Setting reference pattern to:\t" + ref);
                    break;
                case 1:
                    // loc= <locale>
                    loc = LocaleUtility.getLocaleFromName(tokens.next());
                    pat = ((DecimalFormat) NumberFormat.getInstance(loc)).toPattern();
                    logln("Setting locale to:\t" + loc + ", \tand pattern to:\t" + pat);
                    break;
                case 2: // f:
                case 3: // fp:
                case 4: // rt:
                case 5: // p:
                    tok = tokens.next();
                    if (!tok.equals("-")) {
                        pat = tok;
                    }
                    try {
                        fmt = new DecimalFormat(pat, new DecimalFormatSymbols(loc));
                        fmt.setParseStrict(strict);
                    } catch (IllegalArgumentException iae) {
                        errln(where + "Pattern \"" + pat + '"');
                        iae.printStackTrace();
                        tokens.next(); // consume remaining tokens
                        //tokens.next();
                        if (cmd == 3) tokens.next();
                        continue;
                    }
                    str = null;
                    try {
                        if (cmd == 2 || cmd == 3 || cmd == 4) {
                            // f: <pattern or '-'> <number> <exp. string>
                            // fp: <pattern or '-'> <number> <exp. string> <exp. number>
                            // rt: <pattern or '-'> <number> <string>
                            String num = tokens.next();
                            str = tokens.next();
                            Number n = ref.parse(num);
                            assertEquals(where + '"' + pat + "\".format(" + num + ")",
                                    str, fmt.format(n));
                            if (cmd == 3) { // fp:
                                n = ref.parse(tokens.next());
                            }
                            if (cmd != 2) { // != f:
                                assertEquals(where + '"' + pat + "\".parse(\"" + str + "\")",
                                        n, fmt.parse(str));
                            }
                        }
                        // p: <pattern or '-'> <string to parse> <exp. number>
                        else {
                            str = tokens.next();
                            String expstr = tokens.next();
                            Number parsed = fmt.parse(str);
                            Number exp = ref.parse(expstr);
                            assertEquals(where + '"' + pat + "\".parse(\"" + str + "\")",
                                    exp, parsed);
                        }
                    } catch (ParseException e) {
                        errln(where + '"' + pat + "\".parse(\"" + str +
                                "\") threw an exception");
                        e.printStackTrace();
                    }
                    break;
                case 6:
                    // perr: <pattern or '-'> <invalid string>
                    errln("Under construction");
                    return;
                case 7:
                    // pat: <pattern> <exp. toPattern, or '-' or 'err'>
                    String testpat = tokens.next();
                    String exppat  = tokens.next();
                    boolean err    = exppat.equals("err");
                    if (testpat.equals("-")) {
                        if (err) {
                            errln("Invalid command \"pat: - err\" at " +  tokens.describePosition());
                            continue;
                        }
                        testpat = pat;
                    }
                    if (exppat.equals("-")) exppat = testpat;
                    try {
                        DecimalFormat f = null;
                        if (testpat == pat) { // [sic]
                            f = fmt;
                        } else {
                            f = new DecimalFormat(testpat);
                            f.setParseStrict(strict);
                        }
                        if (err) {
                            errln(where + "Invalid pattern \"" + testpat +
                                    "\" was accepted");
                        } else {
                            assertEquals(where + '"' + testpat + "\".toPattern()",
                                    exppat, f.toPattern());
                        }
                    } catch (IllegalArgumentException iae2) {
                        if (err) {
                            logln("Ok: " + where + "Invalid pattern \"" + testpat +
                                    "\" threw an exception");
                        } else {
                            errln(where + "Valid pattern \"" + testpat +
                                    "\" threw an exception");
                            iae2.printStackTrace();
                        }
                    }
                    break;
                case 8: // fpc:
                    tok = tokens.next();
                    if (!tok.equals("-")) {
                        mloc = tok;
                        ULocale l = new ULocale(mloc);
                        try {
                            mfmt = MeasureFormat.getCurrencyFormat(l);
                        } catch (IllegalArgumentException iae) {
                            errln(where + "Loc \"" + tok + '"');
                            iae.printStackTrace();
                            tokens.next(); // consume remaining tokens
                            tokens.next();
                            tokens.next();
                            continue;
                        }
                    }
                    str = null;
                    try {
                        // fpc: <loc or '-'> <curr.amt> <exp. string> <exp. curr.amt>
                        String currAmt = tokens.next();
                        str = tokens.next();
                        CurrencyAmount target = parseCurrencyAmount(currAmt, ref, '/');
                        String formatResult = mfmt.format(target);
                        assertEquals(where + "getCurrencyFormat(" + mloc + ").format(" + currAmt + ")",
                                str, formatResult);
                        target = parseCurrencyAmount(tokens.next(), ref, '/');
                        CurrencyAmount parseResult = (CurrencyAmount) mfmt.parseObject(str);
                        assertEquals(where + "getCurrencyFormat(" + mloc + ").parse(\"" + str + "\")",
                                target, parseResult);
                    } catch (ParseException e) {
                        errln(where + '"' + pat + "\".parse(\"" + str +
                                "\") threw an exception");
                        e.printStackTrace();
                    }
                    break;
                case 9: // strict= true or false
                    strict = "true".equalsIgnoreCase(tokens.next());
                    logln("Setting strict to:\t" + strict);
                    break;
                case -1:
                    errln("Unknown command \"" + tok + "\" at " + tokens.describePosition());
                    return;
                }
            }
        } catch (java.io.IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                reader.close();
            } catch (IOException ignored) {
            }
        }
    }

    @Test
    public void TestFieldPositionDecimal() {
        DecimalFormat nf = (DecimalFormat) com.ibm.icu.text.NumberFormat.getInstance(ULocale.ENGLISH);
        nf.setPositivePrefix("FOO");
        nf.setPositiveSuffix("BA");
        StringBuffer buffer = new StringBuffer();
        FieldPosition fp = new FieldPosition(NumberFormat.Field.DECIMAL_SEPARATOR);
        nf.format(35.47, buffer, fp);
        assertEquals("35.47", "FOO35.47BA", buffer.toString());
        assertEquals("fp begin", 5, fp.getBeginIndex());
        assertEquals("fp end", 6, fp.getEndIndex());
    }

    @Test
    public void TestFieldPositionInteger() {
        DecimalFormat nf = (DecimalFormat) com.ibm.icu.text.NumberFormat.getInstance(ULocale.ENGLISH);
        nf.setPositivePrefix("FOO");
        nf.setPositiveSuffix("BA");
        StringBuffer buffer = new StringBuffer();
        FieldPosition fp = new FieldPosition(NumberFormat.Field.INTEGER);
        nf.format(35.47, buffer, fp);
        assertEquals("35.47", "FOO35.47BA", buffer.toString());
        assertEquals("fp begin", 3, fp.getBeginIndex());
        assertEquals("fp end", 5, fp.getEndIndex());
    }

    @Test
    public void TestFieldPositionFractionButInteger() {
        DecimalFormat nf = (DecimalFormat) com.ibm.icu.text.NumberFormat.getInstance(ULocale.ENGLISH);
        nf.setPositivePrefix("FOO");
        nf.setPositiveSuffix("BA");
        StringBuffer buffer = new StringBuffer();
        FieldPosition fp = new FieldPosition(NumberFormat.Field.FRACTION);
        nf.format(35, buffer, fp);
        assertEquals("35", "FOO35BA", buffer.toString());
        assertEquals("fp begin", 5, fp.getBeginIndex());
        assertEquals("fp end", 5, fp.getEndIndex());
    }

    @Test
    public void TestFieldPositionFraction() {
        DecimalFormat nf = (DecimalFormat) com.ibm.icu.text.NumberFormat.getInstance(ULocale.ENGLISH);
        nf.setPositivePrefix("FOO");
        nf.setPositiveSuffix("BA");
        StringBuffer buffer = new StringBuffer();
        FieldPosition fp = new FieldPosition(NumberFormat.Field.FRACTION);
        nf.format(35.47, buffer, fp);
        assertEquals("35.47", "FOO35.47BA", buffer.toString());
        assertEquals("fp begin", 6, fp.getBeginIndex());
        assertEquals("fp end", 8, fp.getEndIndex());
    }

    @Test
    public void TestFieldPositionCurrency() {
        DecimalFormat nf = (DecimalFormat) com.ibm.icu.text.NumberFormat.getCurrencyInstance(Locale.US);
        double amount = 35.47;
        double negAmount = -34.567;
        FieldPosition cp = new FieldPosition(NumberFormat.Field.CURRENCY);

        StringBuffer buffer0 = new StringBuffer();
        nf.format(amount, buffer0, cp);
        assertEquals("$35.47", "$35.47", buffer0.toString());
        assertEquals("cp begin", 0, cp.getBeginIndex());
        assertEquals("cp end", 1, cp.getEndIndex());

        StringBuffer buffer01 = new StringBuffer();
        nf.format(negAmount, buffer01, cp);
        assertEquals("-$34.57", "-$34.57", buffer01.toString());
        assertEquals("cp begin", 1, cp.getBeginIndex());
        assertEquals("cp end", 2, cp.getEndIndex());

        nf.setCurrency(Currency.getInstance(Locale.FRANCE));
        StringBuffer buffer1 = new StringBuffer();
        nf.format(amount, buffer1, cp);
        assertEquals("€35.47", "€35.47", buffer1.toString());
        assertEquals("cp begin", 0, cp.getBeginIndex());
        assertEquals("cp end", 1, cp.getEndIndex());

        nf.setCurrency(Currency.getInstance(new Locale("fr", "ch", "")));
        StringBuffer buffer2 = new StringBuffer();
        nf.format(amount, buffer2, cp);
        assertEquals("CHF 35.47", "CHF 35.47", buffer2.toString());
        assertEquals("cp begin", 0, cp.getBeginIndex());
        assertEquals("cp end", 3, cp.getEndIndex());

        StringBuffer buffer20 = new StringBuffer();
        nf.format(negAmount, buffer20, cp);
        assertEquals("-CHF 34.57", "-CHF 34.57", buffer20.toString());
        assertEquals("cp begin", 1, cp.getBeginIndex());
        assertEquals("cp end", 4, cp.getEndIndex());

        nf = (DecimalFormat) com.ibm.icu.text.NumberFormat.getCurrencyInstance(Locale.FRANCE);
        StringBuffer buffer3 = new StringBuffer();
        nf.format(amount, buffer3, cp);
        assertEquals("35,47 €", "35,47 €", buffer3.toString());
        assertEquals("cp begin", 6, cp.getBeginIndex());
        assertEquals("cp end", 7, cp.getEndIndex());

        StringBuffer buffer4 = new StringBuffer();
        nf.format(negAmount, buffer4, cp);
        assertEquals("-34,57 €", "-34,57 €", buffer4.toString());
        assertEquals("cp begin", 7, cp.getBeginIndex());
        assertEquals("cp end", 8, cp.getEndIndex());

        nf.setCurrency(Currency.getInstance(new Locale("fr", "ch")));
        StringBuffer buffer5 = new StringBuffer();
        nf.format(negAmount, buffer5, cp);
        assertEquals("-34,57 CHF", "-34,57 CHF", buffer5.toString());
        assertEquals("cp begin", 7, cp.getBeginIndex());
        assertEquals("cp end", 10, cp.getEndIndex());

        NumberFormat plCurrencyFmt = NumberFormat.getInstance(new Locale("fr", "ch"), NumberFormat.PLURALCURRENCYSTYLE);
        StringBuffer buffer6 = new StringBuffer();
        plCurrencyFmt.format(negAmount, buffer6, cp);
        assertEquals("-34.57 francs suisses", "-34.57 francs suisses", buffer6.toString());
        assertEquals("cp begin", 7, cp.getBeginIndex());
        assertEquals("cp end", 21, cp.getEndIndex());

        // Positive value with PLURALCURRENCYSTYLE.
        plCurrencyFmt = NumberFormat.getInstance(new Locale("ja", "ch"), NumberFormat.PLURALCURRENCYSTYLE);
        StringBuffer buffer7 = new StringBuffer();
        plCurrencyFmt.format(amount, buffer7, cp);
        assertEquals("35.47 スイス フラン", "35.47 スイス フラン", buffer7.toString());
        assertEquals("cp begin", 6, cp.getBeginIndex());
        assertEquals("cp end", 13, cp.getEndIndex());

        // PLURALCURRENCYSTYLE for non-ASCII.
        plCurrencyFmt = NumberFormat.getInstance(new Locale("ja", "de"), NumberFormat.PLURALCURRENCYSTYLE);
        StringBuffer buffer8 = new StringBuffer();
        plCurrencyFmt.format(negAmount, buffer8, cp);
        assertEquals("-34.57 ユーロ", "-34.57 ユーロ", buffer8.toString());
        assertEquals("cp begin", 7, cp.getBeginIndex());
        assertEquals("cp end", 10, cp.getEndIndex());

        nf = (DecimalFormat) com.ibm.icu.text.NumberFormat.getCurrencyInstance(Locale.JAPAN);
        nf.setCurrency(Currency.getInstance(new Locale("ja", "jp")));
        StringBuffer buffer9 = new StringBuffer();
        nf.format(negAmount, buffer9, cp);
        assertEquals("-￥35", "-￥35", buffer9.toString());
        assertEquals("cp begin", 1, cp.getBeginIndex());
        assertEquals("cp end", 2, cp.getEndIndex());

        // Negative value with PLURALCURRENCYSTYLE.
        plCurrencyFmt = NumberFormat.getInstance(new Locale("ja", "ch"), NumberFormat.PLURALCURRENCYSTYLE);
        StringBuffer buffer10 = new StringBuffer();
        plCurrencyFmt.format(negAmount, buffer10, cp);
        assertEquals("-34.57 スイス フラン", "-34.57 スイス フラン", buffer10.toString());
        assertEquals("cp begin", 7, cp.getBeginIndex());
        assertEquals("cp end", 14, cp.getEndIndex());

        // Nagative value with PLURALCURRENCYSTYLE, Arabic digits.
        nf = (DecimalFormat) com.ibm.icu.text.NumberFormat.getCurrencyInstance(new Locale("ar", "eg"));
        plCurrencyFmt = NumberFormat.getInstance(new Locale("ar", "eg"), NumberFormat.PLURALCURRENCYSTYLE);
        StringBuffer buffer11 = new StringBuffer();
        plCurrencyFmt.format(negAmount, buffer11, cp);
        assertEquals("؜-٣٤٫٥٧ جنيه مصري", "؜-٣٤٫٥٧ جنيه مصري", buffer11.toString());
        assertEquals("cp begin", 8, cp.getBeginIndex());
        assertEquals("cp end", 17, cp.getEndIndex());
    }

    @Test
    public void TestRounding() {
        DecimalFormat nf = (DecimalFormat) com.ibm.icu.text.NumberFormat.getInstance(ULocale.ENGLISH);
        if (false) { // for debugging specific value
            nf.setRoundingMode(BigDecimal.ROUND_HALF_UP);
            checkRounding(nf, new BigDecimal("300.0300000000"), 0, new BigDecimal("0.020000000"));
        }
        // full tests
        int[] roundingIncrements = {1, 2, 5, 20, 50, 100};
        int[] testValues = {0, 300};
        for (int j = 0; j < testValues.length; ++j) {
            for (int mode = BigDecimal.ROUND_UP; mode < BigDecimal.ROUND_HALF_EVEN; ++mode) {
                nf.setRoundingMode(mode);
                for (int increment = 0; increment < roundingIncrements.length; ++increment) {
                    BigDecimal base = new BigDecimal(testValues[j]);
                    BigDecimal rInc = new BigDecimal(roundingIncrements[increment]);
                    checkRounding(nf,  base, 20, rInc);
                    rInc = new BigDecimal("1.000000000").divide(rInc);
                    checkRounding(nf,  base, 20, rInc);
                }
            }
        }
    }

    @Test
    public void TestRoundingPattern() {
        class TestRoundingPatternItem {
            String     pattern;
            BigDecimal roundingIncrement;
            double     testCase;
            String     expected;

            TestRoundingPatternItem(String pattern, BigDecimal roundingIncrement, double testCase, String expected) {
                this.pattern = pattern;
                this.roundingIncrement = roundingIncrement;
                this.testCase = testCase;
                this.expected = expected;
            }
        };

        TestRoundingPatternItem []tests = {
                new TestRoundingPatternItem("##0.65", new BigDecimal("0.65"), 1.234, "1.30"),
                new TestRoundingPatternItem("#50", new BigDecimal("50"), 1230, "1250")
        };

        DecimalFormat df = (DecimalFormat) com.ibm.icu.text.NumberFormat.getInstance(ULocale.ENGLISH);
        String result;
        for (int i = 0; i < tests.length; i++) {
            df.applyPattern(tests[i].pattern);

            result = df.format(tests[i].testCase);

            if (!tests[i].expected.equals(result)) {
                errln("String Pattern Rounding Test Failed: Pattern: \"" + tests[i].pattern + "\" Number: " + tests[i].testCase + " - Got: " + result + " Expected: " + tests[i].expected);
            }

            df.setRoundingIncrement(tests[i].roundingIncrement);

            result = df.format(tests[i].testCase);

            if (!tests[i].expected.equals(result)) {
                errln("BigDecimal Rounding Test Failed: Pattern: \"" + tests[i].pattern + "\" Number: " + tests[i].testCase + " - Got: " + result + " Expected: " + tests[i].expected);
            }
        }
    }

    @Test
    public void TestBigDecimalRounding() {
        String figure = "50.000000004";
        Double dbl = new Double(figure);
        BigDecimal dec = new BigDecimal(figure);

        DecimalFormat f = (DecimalFormat) NumberFormat.getInstance();
        f.applyPattern("00.00######");

        assertEquals("double format", "50.00", f.format(dbl));
        assertEquals("bigdec format", "50.00", f.format(dec));

        int maxFracDigits = f.getMaximumFractionDigits();
        BigDecimal roundingIncrement = new BigDecimal("1").movePointLeft(maxFracDigits);

        f.setRoundingIncrement(roundingIncrement);
        f.setRoundingMode(BigDecimal.ROUND_DOWN);
        assertEquals("Rounding down", f.format(dbl), f.format(dec));

        f.setRoundingIncrement(roundingIncrement);
        f.setRoundingMode(BigDecimal.ROUND_HALF_UP);
        assertEquals("Rounding half up", f.format(dbl), f.format(dec));
    }

    void checkRounding(DecimalFormat nf, BigDecimal base, int iterations, BigDecimal increment) {
        nf.setRoundingIncrement(increment.toBigDecimal());
        BigDecimal lastParsed = new BigDecimal(Integer.MIN_VALUE); // used to make sure that rounding is monotonic
        for (int i = -iterations; i <= iterations; ++i) {
            BigDecimal iValue = base.add(increment.multiply(new BigDecimal(i)).movePointLeft(1));
            BigDecimal smallIncrement = new BigDecimal("0.00000001");
            if (iValue.signum() != 0) {
                smallIncrement.multiply(iValue); // scale unless zero
            }
            // we not only test the value, but some values in a small range around it.
            lastParsed = checkRound(nf, iValue.subtract(smallIncrement), lastParsed);
            lastParsed = checkRound(nf, iValue, lastParsed);
            lastParsed = checkRound(nf, iValue.add(smallIncrement), lastParsed);
        }
    }

    private BigDecimal checkRound(DecimalFormat nf, BigDecimal iValue, BigDecimal lastParsed) {
        String formatedBigDecimal = nf.format(iValue);
        String formattedDouble = nf.format(iValue.doubleValue());
        if (!equalButForTrailingZeros(formatedBigDecimal, formattedDouble)) {

            errln("Failure at: " + iValue + " (" + iValue.doubleValue() + ")"
                    + ",\tRounding-mode: " + roundingModeNames[nf.getRoundingMode()]
                            + ",\tRounding-increment: " + nf.getRoundingIncrement()
                            + ",\tdouble: " + formattedDouble
                            + ",\tBigDecimal: " + formatedBigDecimal);

        } else {
            logln("Value: " + iValue
                    + ",\tRounding-mode: " + roundingModeNames[nf.getRoundingMode()]
                            + ",\tRounding-increment: " + nf.getRoundingIncrement()
                            + ",\tdouble: " + formattedDouble
                            + ",\tBigDecimal: " + formatedBigDecimal);
        }
        try {
            // Number should have compareTo(...)
            BigDecimal parsed = toBigDecimal(nf.parse(formatedBigDecimal));
            if (lastParsed.compareTo(parsed) > 0) {
                errln("Rounding wrong direction!: " + lastParsed + " > " + parsed);
            }
            lastParsed = parsed;
        } catch (ParseException e) {
            errln("Parse Failure with: " + formatedBigDecimal);
        }
        return lastParsed;
    }

    static BigDecimal toBigDecimal(Number number) {
        return number instanceof BigDecimal ? (BigDecimal) number
                : number instanceof BigInteger ? new BigDecimal((BigInteger)number)
        : number instanceof java.math.BigDecimal ? new BigDecimal((java.math.BigDecimal)number)
                : number instanceof Double ? new BigDecimal(number.doubleValue())
        : number instanceof Float ? new BigDecimal(number.floatValue())
                : new BigDecimal(number.longValue());
    }

    static String[] roundingModeNames = {
        "ROUND_UP", "ROUND_DOWN", "ROUND_CEILING", "ROUND_FLOOR",
        "ROUND_HALF_UP", "ROUND_HALF_DOWN", "ROUND_HALF_EVEN",
        "ROUND_UNNECESSARY"
    };

    private static boolean equalButForTrailingZeros(String formatted1, String formatted2) {
        if (formatted1.length() == formatted2.length()) return formatted1.equals(formatted2);
        return stripFinalZeros(formatted1).equals(stripFinalZeros(formatted2));
    }

    private static String stripFinalZeros(String formatted) {
        int len1 = formatted.length();
        char ch;
        while (len1 > 0 && ((ch = formatted.charAt(len1-1)) == '0' || ch == '.')) --len1;
        if (len1==1 && ((ch = formatted.charAt(len1-1)) == '-')) --len1;
        return formatted.substring(0,len1);
    }

    //------------------------------------------------------------------
    // Support methods
    //------------------------------------------------------------------

    /** Format-Parse test */
    public void expect2(NumberFormat fmt, Number n, String exp) {
        // Don't round-trip format test, since we explicitly do it
        expect(fmt, n, exp, false);
        expect(fmt, exp, n);
    }
    /** Format-Parse test */
    public void expect3(NumberFormat fmt, Number n, String exp) {
        // Don't round-trip format test, since we explicitly do it
        expect_rbnf(fmt, n, exp, false);
        expect_rbnf(fmt, exp, n);
    }

    /** Format-Parse test (convenience) */
    public void expect2(NumberFormat fmt, double n, String exp) {
        expect2(fmt, new Double(n), exp);
    }
    /** RBNF Format-Parse test (convenience) */
    public void expect3(NumberFormat fmt, double n, String exp) {
        expect3(fmt, new Double(n), exp);
    }

    /** Format-Parse test (convenience) */
    public void expect2(NumberFormat fmt, long n, String exp) {
        expect2(fmt, new Long(n), exp);
    }
    /** RBNF Format-Parse test (convenience) */
    public void expect3(NumberFormat fmt, long n, String exp) {
        expect3(fmt, new Long(n), exp);
    }

    /** Format test */
    public void expect(NumberFormat fmt, Number n, String exp, boolean rt) {
        StringBuffer saw = new StringBuffer();
        FieldPosition pos = new FieldPosition(0);
        fmt.format(n, saw, pos);
        String pat = ((DecimalFormat)fmt).toPattern();
        if (saw.toString().equals(exp)) {
            logln("Ok   " + n + " x " +
                    pat + " = \"" +
                    saw + "\"");
            // We should be able to round-trip the formatted string =>
            // number => string (but not the other way around: number
            // => string => number2, might have number2 != number):
            if (rt) {
                try {
                    Number n2 = fmt.parse(exp);
                    StringBuffer saw2 = new StringBuffer();
                    fmt.format(n2, saw2, pos);
                    if (!saw2.toString().equals(exp)) {
                        errln("expect() format test rt, locale " + fmt.getLocale(ULocale.VALID_LOCALE) +
                                ", FAIL \"" + exp + "\" => " + n2 + " => \"" + saw2 + '"');
                    }
                } catch (ParseException e) {
                    errln("expect() format test rt, locale " + fmt.getLocale(ULocale.VALID_LOCALE) +
                            ", " + e.getMessage());
                    return;
                }
            }
        } else {
            errln("expect() format test, locale " + fmt.getLocale(ULocale.VALID_LOCALE) +
                    ", FAIL " + n + " x " + pat + " = \"" + saw + "\", expected \"" + exp + "\"");
        }
    }
    /** RBNF format test */
    public void expect_rbnf(NumberFormat fmt, Number n, String exp, boolean rt) {
        StringBuffer saw = new StringBuffer();
        FieldPosition pos = new FieldPosition(0);
        fmt.format(n, saw, pos);
        if (saw.toString().equals(exp)) {
            logln("Ok   " + n + " = \"" +
                    saw + "\"");
            // We should be able to round-trip the formatted string =>
            // number => string (but not the other way around: number
            // => string => number2, might have number2 != number):
            if (rt) {
                try {
                    Number n2 = fmt.parse(exp);
                    StringBuffer saw2 = new StringBuffer();
                    fmt.format(n2, saw2, pos);
                    if (!saw2.toString().equals(exp)) {
                        errln("expect_rbnf() format test rt, locale " + fmt.getLocale(ULocale.VALID_LOCALE) +
                                ", FAIL \"" + exp + "\" => " + n2 + " => \"" + saw2 + '"');
                    }
                } catch (ParseException e) {
                    errln("expect_rbnf() format test rt, locale " + fmt.getLocale(ULocale.VALID_LOCALE) +
                            ", " + e.getMessage());
                    return;
                }
            }
        } else {
            errln("expect_rbnf() format test, locale " + fmt.getLocale(ULocale.VALID_LOCALE) +
                    ", FAIL " + n + " = \"" + saw + "\", expected \"" + exp + "\"");
        }
    }

    /** Format test (convenience) */
    public void expect(NumberFormat fmt, Number n, String exp) {
        expect(fmt, n, exp, true);
    }

    /** Format test (convenience) */
    public void expect(NumberFormat fmt, double n, String exp) {
        expect(fmt, new Double(n), exp);
    }

    /** Format test (convenience) */
    public void expect(NumberFormat fmt, long n, String exp) {
        expect(fmt, new Long(n), exp);
    }

    /** Parse test */
    public void expect(NumberFormat fmt, String str, Number n) {
        Number num = null;
        try {
            num = fmt.parse(str);
        } catch (ParseException e) {
            errln(e.getMessage());
            return;
        }
        String pat = ((DecimalFormat)fmt).toPattern();
        // A little tricky here -- make sure Double(12345.0) and
        // Long(12345) match.
        if (num.equals(n) || num.doubleValue() == n.doubleValue()) {
            logln("Ok   \"" + str + "\" x " +
                    pat + " = " +
                    num);
        } else {
            errln("expect() parse test, locale " + fmt.getLocale(ULocale.VALID_LOCALE) +
                    ", FAIL \"" + str + "\" x " + pat + " = " + num + ", expected " + n);
        }
    }

    /** RBNF Parse test */
    public void expect_rbnf(NumberFormat fmt, String str, Number n) {
        Number num = null;
        try {
            num = fmt.parse(str);
        } catch (ParseException e) {
            errln(e.getMessage());
            return;
        }
        // A little tricky here -- make sure Double(12345.0) and
        // Long(12345) match.
        if (num.equals(n) || num.doubleValue() == n.doubleValue()) {
            logln("Ok   \"" + str + " = " +
                    num);
        } else {
            errln("expect_rbnf() parse test, locale " + fmt.getLocale(ULocale.VALID_LOCALE) +
                    ", FAIL \"" + str + " = " + num + ", expected " + n);
        }
    }

    /** Parse test (convenience) */
    public void expect(NumberFormat fmt, String str, double n) {
        expect(fmt, str, new Double(n));
    }

    /** Parse test (convenience) */
    public void expect(NumberFormat fmt, String str, long n) {
        expect(fmt, str, new Long(n));
    }

    /** Parse test */
    public void expectParseException(DecimalFormat fmt, String str, Number n) {
        Number num = null;
        try {
            num = fmt.parse(str);
            errln("Expected failure, but passed: " + n + " on " + fmt.toPattern() + " -> " + num);
        } catch (ParseException e) {
        }
    }

    private void expectCurrency(NumberFormat nf, Currency curr,
            double value, String string) {
        DecimalFormat fmt = (DecimalFormat) nf;
        if (curr != null) {
            fmt.setCurrency(curr);
        }
        String s = fmt.format(value).replace('\u00A0', ' ');

        if (s.equals(string)) {
            logln("Ok: " + value + " x " + curr + " => " + s);
        } else {
            errln("FAIL: " + value + " x " + curr + " => " + s +
                    ", expected " + string);
        }
    }

    public void expectPad(DecimalFormat fmt, String pat, int pos) {
        expectPad(fmt, pat, pos, 0, (char)0);
    }

    public void expectPad(DecimalFormat fmt, final String pat, int pos, int width, final char pad) {
        int apos = 0, awidth = 0;
        char apadStr;
        try {
            fmt.applyPattern(pat);
            apos = fmt.getPadPosition();
            awidth = fmt.getFormatWidth();
            apadStr = fmt.getPadCharacter();
        } catch (Exception e) {
            apos = -1;
            awidth = width;
            apadStr = pad;
        }

        if (apos == pos && awidth == width && apadStr == pad) {
            logln("Ok   \"" + pat + "\" pos="
                    + apos + ((pos == -1) ? "" : " width=" + awidth + " pad=" + apadStr));
        } else {
            errln("FAIL \"" + pat + "\" pos=" + apos + " width="
                    + awidth + " pad=" + apadStr + ", expected "
                    + pos + " " + width + " " + pad);
        }
    }

    public void expectPat(DecimalFormat fmt, final String exp) {
        String pat = fmt.toPattern();
        if (pat.equals(exp)) {
            logln("Ok   \"" + pat + "\"");
        } else {
            errln("FAIL \"" + pat + "\", expected \"" + exp + "\"");
        }
    }


    private void expectParseCurrency(NumberFormat fmt, Currency expected, String text) {
        ParsePosition pos = new ParsePosition(0);
        CurrencyAmount currencyAmount = fmt.parseCurrency(text, pos);
        assertTrue("Parse of " + text + " should have succeeded.", pos.getIndex() > 0);
        assertEquals("Currency should be correct.", expected, currencyAmount.getCurrency());
    }

    @Test
    public void TestJB3832(){
        ULocale locale = new ULocale("pt_PT@currency=PTE");
        NumberFormat format = NumberFormat.getCurrencyInstance(locale);
        Currency curr = Currency.getInstance(locale);
        logln("\nName of the currency is: " + curr.getName(locale, Currency.LONG_NAME, new boolean[] {false}));
        CurrencyAmount cAmt = new CurrencyAmount(1150.50, curr);
        logln("CurrencyAmount object's hashCode is: " + cAmt.hashCode()); //cover hashCode
        String str = format.format(cAmt);
        String expected = "1,150$50\u00a0\u200b";
        if(!expected.equals(str)){
            errln("Did not get the expected output Expected: "+expected+" Got: "+ str);
        }
    }

    @Test
    public void TestScientificWithGrouping() {
        // Grouping separators are not allowed in the pattern, but we can enable them via the API.
        DecimalFormat df = new DecimalFormat("###0.000E0");
        df.setGroupingUsed(true);
        df.setGroupingSize(3);
        expect2(df, 123, "123.0E0");
        expect2(df, 1234, "1,234E0");
        expect2(df, 12340, "1.234E4");
    }

    @Test
    public void TestStrictParse() {
        // Pass both strict and lenient:
        String[] pass = {
                "0",           // single zero before end of text is not leading
                "0 ",          // single zero at end of number is not leading
                "0.",          // single zero before period (or decimal, it's ambiguous) is not leading
                "0,",          // single zero before comma (not group separator) is not leading
                "0.0",         // single zero before decimal followed by digit is not leading
                "0. ",         // same as above before period (or decimal) is not leading
                "0.100,5",     // comma stops parse of decimal (no grouping)
                "0.100,,5",    // two commas also stops parse
                ".00",         // leading decimal is ok, even with zeros
                "1234567",     // group separators are not required
                "12345, ",     // comma not followed by digit is not a group separator, but end of number
                "1,234, ",     // if group separator is present, group sizes must be appropriate
                "1,234,567",   // ...secondary too
                "0E",          // an exponent not followed by zero or digits is not an exponent
                "00",          // leading zero before zero - used to be error - see ticket #7913
                "012",         // leading zero before digit - used to be error - see ticket #7913
                "0,456",       // leading zero before group separator - used to be error - see ticket #7913
                "999,999",     // see ticket #6863
                "-99,999",     // see ticket #6863
                "-999,999",    // see ticket #6863
                "-9,999,999",  // see ticket #6863
        };
        // Pass lenient, fail strict:
        String[] fail = {
                "1,2",       // wrong number of digits after group separator
                ",.02",      // leading group separator before decimal
                "1,.02",     // group separator before decimal
                ",0",        // leading group separator before a single digit
                ",1",        // leading group separator before a single digit
                "1,45",      // wrong number of digits in primary group
                "1,45 that", // wrong number of digits in primary group
                "1,45.34",   // wrong number of digits in primary group
                "1234,567",  // wrong number of digits in secondary group
                "12,34,567", // wrong number of digits in secondary group
                "1,23,456,7890", // wrong number of digits in primary and secondary groups
        };
        // Fail both lenient and strict:
        String[] failBoth = {
        };

        DecimalFormat nf = (DecimalFormat) NumberFormat.getInstance(Locale.ENGLISH);
        runStrictParseBatch(nf, pass, fail, failBoth);

        String[] scientificPass = {
                "0E2",      // single zero before exponent is ok
                "1234E2",   // any number of digits before exponent is ok
                "1,234E",   // an exponent string not followed by zero or digits is not an exponent
                "00E2",     // leading zeroes now allowed in strict mode - see ticket #
        };
        String[] scientificFail = {
        };
        String[] scientificFailBoth = {
        };

        nf = (DecimalFormat) NumberFormat.getInstance(Locale.ENGLISH);
        runStrictParseBatch(nf, scientificPass, scientificFail, scientificFailBoth);

        String[] mixedPass = {
                "12,34,567",
                "12,34,567,",
                "12,34,567, that",
                "12,34,567 that",
        };
        String[] mixedFail = {
                "12,34,56",
                "12,34,56,",
                "12,34,56, that ",
                "12,34,56 that",
        };
        String[] mixedFailBoth = {
        };

        nf = new DecimalFormat("#,##,##0.#");
        runStrictParseBatch(nf, mixedPass, mixedFail, mixedFailBoth);
    }

    void runStrictParseBatch(DecimalFormat nf, String[] pass, String[] fail, String[] failBoth) {
        nf.setParseStrict(false);
        runStrictParseTests("should pass", nf, pass, true);
        runStrictParseTests("should also pass", nf, fail, true);
        runStrictParseTests("should fail", nf, failBoth, false);
        nf.setParseStrict(true);
        runStrictParseTests("should still pass", nf, pass, true);
        runStrictParseTests("should fail", nf, fail, false);
        runStrictParseTests("should still fail", nf, failBoth, false);
    }

    void runStrictParseTests(String msg, DecimalFormat nf, String[] tests, boolean pass) {
        logln("");
        logln("pattern: '" + nf.toPattern() + "'");
        logln(msg);
        for (int i = 0; i < tests.length; ++i) {
            String str = tests[i];
            ParsePosition pp = new ParsePosition(0);
            Number n = nf.parse(str, pp);
            String formatted = n != null ? nf.format(n) : "null";
            String err = pp.getErrorIndex() == -1 ? "" : "(error at " + pp.getErrorIndex() + ")";
            if ((err.length() == 0) != pass) {
                errln("'" + str + "' parsed '" +
                        str.substring(0, pp.getIndex()) +
                        "' returned " + n + " formats to '" +
                        formatted + "' " + err);
            } else {
                if (err.length() > 0) {
                    err = "got expected " + err;
                }
                logln("'" + str + "' parsed '" +
                        str.substring(0, pp.getIndex()) +
                        "' returned " + n + " formats to '" +
                        formatted + "' " + err);
            }
        }
    }

    @Test
    public void TestJB5251(){
        //save default locale
        ULocale defaultLocale = ULocale.getDefault();
        ULocale.setDefault(new ULocale("qr_QR"));
        try {
            NumberFormat.getInstance();
        }
        catch (Exception e) {
            errln("Numberformat threw exception for non-existent locale. It should use the default.");
        }
        //reset default locale
        ULocale.setDefault(defaultLocale);
    }

    @Test
    public void TestParseReturnType() {
        String[] defaultLong = {
                "123",
                "123.0",
                "0.0",
                "-9223372036854775808", // Min Long
                "9223372036854775807" // Max Long
        };

        String[] defaultNonLong = {
                "12345678901234567890",
                "9223372036854775808",
                "-9223372036854775809"
        };

        String[] doubles = {
                "-0.0",
                "NaN",
                "\u221E"    // Infinity
        };

        DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US);
        DecimalFormat nf = new DecimalFormat("#.#", sym);

        if (nf.isParseBigDecimal()) {
            errln("FAIL: isParseDecimal() must return false by default");
        }

        // isParseBigDecimal() is false
        for (int i = 0; i < defaultLong.length; i++) {
            try {
                Number n = nf.parse(defaultLong[i]);
                if (!(n instanceof Long)) {
                    errln("FAIL: parse does not return Long instance");
                }
            } catch (ParseException e) {
                errln("parse of '" + defaultLong[i] + "' threw exception: " + e);
            }
        }
        for (int i = 0; i < defaultNonLong.length; i++) {
            try {
                Number n = nf.parse(defaultNonLong[i]);
                if (n instanceof Long) {
                    errln("FAIL: parse returned a Long");
                }
            } catch (ParseException e) {
                errln("parse of '" + defaultNonLong[i] + "' threw exception: " + e);
            }
        }
        // parse results for doubls must be always Double
        for (int i = 0; i < doubles.length; i++) {
            try {
                Number n = nf.parse(doubles[i]);
                if (!(n instanceof Double)) {
                    errln("FAIL: parse does not return Double instance");
                }
            } catch (ParseException e) {
                errln("parse of '" + doubles[i] + "' threw exception: " + e);
            }
        }

        // force this DecimalFormat to return BigDecimal
        nf.setParseBigDecimal(true);
        if (!nf.isParseBigDecimal()) {
            errln("FAIL: isParseBigDecimal() must return true");
        }

        // isParseBigDecimal() is true
        for (int i = 0; i < defaultLong.length + defaultNonLong.length; i++) {
            String input = (i < defaultLong.length) ? defaultLong[i] : defaultNonLong[i - defaultLong.length];
            try {
                Number n = nf.parse(input);
                if (!(n instanceof BigDecimal)) {
                    errln("FAIL: parse does not return BigDecimal instance");
                }
            } catch (ParseException e) {
                errln("parse of '" + input + "' threw exception: " + e);
            }
        }
        // parse results for doubls must be always Double
        for (int i = 0; i < doubles.length; i++) {
            try {
                Number n = nf.parse(doubles[i]);
                if (!(n instanceof Double)) {
                    errln("FAIL: parse does not return Double instance");
                }
            } catch (ParseException e) {
                errln("parse of '" + doubles[i] + "' threw exception: " + e);
            }
        }
    }

    @Test
    public void TestNonpositiveMultiplier() {
        DecimalFormat df = new DecimalFormat("0");

        // test zero multiplier

        try {
            df.setMultiplier(0);

            // bad
            errln("DecimalFormat.setMultiplier(0) did not throw an IllegalArgumentException");
        } catch (IllegalArgumentException ex) {
            // good
        }

        // test negative multiplier

        try {
            df.setMultiplier(-1);

            if (df.getMultiplier() != -1) {
                errln("DecimalFormat.setMultiplier(-1) did not change the multiplier to -1");
                return;
            }

            // good
        } catch (IllegalArgumentException ex) {
            // bad
            errln("DecimalFormat.setMultiplier(-1) threw an IllegalArgumentException");
            return;
        }

        expect(df, "1122.123", -1122.123);
        expect(df, "-1122.123", 1122.123);
        expect(df, "1.2", -1.2);
        expect(df, "-1.2", 1.2);

        expect2(df, Long.MAX_VALUE, BigInteger.valueOf(Long.MAX_VALUE).negate().toString());
        expect2(df, Long.MIN_VALUE, BigInteger.valueOf(Long.MIN_VALUE).negate().toString());
        expect2(df, Long.MAX_VALUE / 2, BigInteger.valueOf(Long.MAX_VALUE / 2).negate().toString());
        expect2(df, Long.MIN_VALUE / 2, BigInteger.valueOf(Long.MIN_VALUE / 2).negate().toString());

        expect2(df, BigDecimal.valueOf(Long.MAX_VALUE), BigDecimal.valueOf(Long.MAX_VALUE).negate().toString());
        expect2(df, BigDecimal.valueOf(Long.MIN_VALUE), BigDecimal.valueOf(Long.MIN_VALUE).negate().toString());

        expect2(df, java.math.BigDecimal.valueOf(Long.MAX_VALUE), java.math.BigDecimal.valueOf(Long.MAX_VALUE).negate().toString());
        expect2(df, java.math.BigDecimal.valueOf(Long.MIN_VALUE), java.math.BigDecimal.valueOf(Long.MIN_VALUE).negate().toString());
    }

    @Test
    public void TestJB5358() {
        int numThreads = 10;
        String numstr = "12345";
        double expected = 12345;
        DecimalFormatSymbols sym = new DecimalFormatSymbols(Locale.US);
        DecimalFormat fmt = new DecimalFormat("#.#", sym);
        ArrayList errors = new ArrayList();

        ParseThreadJB5358[] threads = new ParseThreadJB5358[numThreads];
        for (int i = 0; i < numThreads; i++) {
            threads[i] = new ParseThreadJB5358((DecimalFormat)fmt.clone(), numstr, expected, errors);
            threads[i].start();
        }
        for (int i = 0; i < numThreads; i++) {
            try {
                threads[i].join();
            } catch (InterruptedException ie) {
                ie.printStackTrace();
            }
        }
        if (errors.size() != 0) {
            StringBuffer errBuf = new StringBuffer();
            for (int i = 0; i < errors.size(); i++) {
                errBuf.append((String)errors.get(i));
                errBuf.append("\n");
            }
            errln("FAIL: " + errBuf);
        }
    }

    static private class ParseThreadJB5358 extends Thread {
        private final DecimalFormat decfmt;
        private final String numstr;
        private final double expect;
        private final ArrayList errors;

        public ParseThreadJB5358(DecimalFormat decfmt, String numstr, double expect, ArrayList errors) {
            this.decfmt = decfmt;
            this.numstr = numstr;
            this.expect = expect;
            this.errors = errors;
        }

        @Override
        public void run() {
            for (int i = 0; i < 10000; i++) {
                try {
                    Number n = decfmt.parse(numstr);
                    if (n.doubleValue() != expect) {
                        synchronized(errors) {
                            errors.add(new String("Bad parse result - expected:" + expect + " actual:" + n.doubleValue()));
                        }
                    }
                } catch (Throwable t) {
                    synchronized(errors) {
                        errors.add(new String(t.getClass().getName() + " - " + t.getMessage()));
                    }
                }
            }
        }
    }

    @Test
    public void TestSetCurrency() {
        DecimalFormatSymbols decf1 = DecimalFormatSymbols.getInstance(ULocale.US);
        DecimalFormatSymbols decf2 = DecimalFormatSymbols.getInstance(ULocale.US);
        decf2.setCurrencySymbol("UKD");
        DecimalFormat format1 = new DecimalFormat("000.000", decf1);
        DecimalFormat format2 = new DecimalFormat("000.000", decf2);
        Currency euro = Currency.getInstance("EUR");
        format1.setCurrency(euro);
        format2.setCurrency(euro);
        assertEquals("Reset with currency symbol", format1, format2);
    }

    /*
     * Testing the method public StringBuffer format(Object number, ...)
     */
    @Test
    public void TestFormat() {
        NumberFormat nf = NumberFormat.getInstance();
        StringBuffer sb = new StringBuffer("dummy");
        FieldPosition fp = new FieldPosition(0);

        // Tests when "if (number instanceof Long)" is true
        try {
            nf.format(new Long("0"), sb, fp);
        } catch (Exception e) {
            errln("NumberFormat.format(Object number, ...) was not suppose to "
                    + "return an exception for a Long object. Error: " + e);
        }

        // Tests when "else if (number instanceof BigInteger)" is true
        try {
            nf.format((Object)new BigInteger("0"), sb, fp);
        } catch (Exception e) {
            errln("NumberFormat.format(Object number, ...) was not suppose to "
                    + "return an exception for a BigInteger object. Error: " + e);
        }

        // Tests when "else if (number instanceof java.math.BigDecimal)" is true
        try {
            nf.format((Object)new java.math.BigDecimal("0"), sb, fp);
        } catch (Exception e) {
            errln("NumberFormat.format(Object number, ...) was not suppose to "
                    + "return an exception for a java.math.BigDecimal object. Error: " + e);
        }

        // Tests when "else if (number instanceof com.ibm.icu.math.BigDecimal)" is true
        try {
            nf.format((Object)new com.ibm.icu.math.BigDecimal("0"), sb, fp);
        } catch (Exception e) {
            errln("NumberFormat.format(Object number, ...) was not suppose to "
                    + "return an exception for a com.ibm.icu.math.BigDecimal object. Error: " + e);
        }

        // Tests when "else if (number instanceof CurrencyAmount)" is true
        try {
            CurrencyAmount ca = new CurrencyAmount(0.0, Currency.getInstance(new ULocale("en_US")));
            nf.format((Object)ca, sb, fp);
        } catch (Exception e) {
            errln("NumberFormat.format(Object number, ...) was not suppose to "
                    + "return an exception for a CurrencyAmount object. Error: " + e);
        }

        // Tests when "else if (number instanceof Number)" is true
        try {
            nf.format(0.0, sb, fp);
        } catch (Exception e) {
            errln("NumberFormat.format(Object number, ...) was not suppose to "
                    + "to return an exception for a Number object. Error: " + e);
        }

        // Tests when "else" is true
        try {
            nf.format(new Object(), sb, fp);
            errln("NumberFormat.format(Object number, ...) was suppose to "
                    + "return an exception for an invalid object.");
        } catch (Exception e) {
        }

        try {
            nf.format(new String("dummy"), sb, fp);
            errln("NumberFormat.format(Object number, ...) was suppose to "
                    + "return an exception for an invalid object.");
        } catch (Exception e) {
        }
    }

    /*
     * Coverage tests for the implementation of abstract format methods not being called otherwise
     */
    @Test
    public void TestFormatAbstractImplCoverage() {
        NumberFormat df = DecimalFormat.getInstance(Locale.ENGLISH);
        NumberFormat cdf = CompactDecimalFormat.getInstance(Locale.ENGLISH, CompactDecimalFormat.CompactStyle.SHORT);
        NumberFormat rbf = new RuleBasedNumberFormat(ULocale.ENGLISH, RuleBasedNumberFormat.SPELLOUT);

        /*
         *  Test  NumberFormat.format(BigDecimal,StringBuffer,FieldPosition)
         */
        StringBuffer sb = new StringBuffer();
        String result = df.format(new BigDecimal(2000.43), sb, new FieldPosition(0)).toString();
        if (!"2,000.43".equals(result)) {
            errln("DecimalFormat failed. Expected: 2,000.43 - Actual: " + result);
        }

        sb.delete(0, sb.length());
        result = cdf.format(new BigDecimal(2000.43), sb, new FieldPosition(0)).toString();
        if (!"2K".equals(result)) {
            errln("DecimalFormat failed. Expected: 2K - Actual: " + result);
        }

        sb.delete(0, sb.length());
        result = rbf.format(new BigDecimal(2000.43), sb, new FieldPosition(0)).toString();
        if (!"two thousand point four three".equals(result)) {
            errln("DecimalFormat failed. Expected: 'two thousand point four three' - Actual: '" + result + "'");
        }
    }

    /*
     * Tests the method public final static NumberFormat getInstance(int style) public static NumberFormat
     * getInstance(Locale inLocale, int style) public static NumberFormat getInstance(ULocale desiredLocale, int choice)
     */
    @Test
    public void TestGetInstance() {
        // Tests "public final static NumberFormat getInstance(int style)"
        int maxStyle = NumberFormat.STANDARDCURRENCYSTYLE;

        int[] invalid_cases = { NumberFormat.NUMBERSTYLE - 1, NumberFormat.NUMBERSTYLE - 2,
                maxStyle + 1, maxStyle + 2 };

        for (int i = NumberFormat.NUMBERSTYLE; i < maxStyle; i++) {
            try {
                NumberFormat.getInstance(i);
            } catch (Exception e) {
                errln("NumberFormat.getInstance(int style) was not suppose to "
                        + "return an exception for passing value of " + i);
            }
        }

        for (int i = 0; i < invalid_cases.length; i++) {
            try {
                NumberFormat.getInstance(invalid_cases[i]);
                errln("NumberFormat.getInstance(int style) was suppose to "
                        + "return an exception for passing value of " + invalid_cases[i]);
            } catch (Exception e) {
            }
        }

        // Tests "public static NumberFormat getInstance(Locale inLocale, int style)"
        String[] localeCases = { "en_US", "fr_FR", "de_DE", "jp_JP" };

        for (int i = NumberFormat.NUMBERSTYLE; i < maxStyle; i++) {
            for (int j = 0; j < localeCases.length; j++) {
                try {
                    NumberFormat.getInstance(new Locale(localeCases[j]), i);
                } catch (Exception e) {
                    errln("NumberFormat.getInstance(Locale inLocale, int style) was not suppose to "
                            + "return an exception for passing value of " + localeCases[j] + ", " + i);
                }
            }
        }

        // Tests "public static NumberFormat getInstance(ULocale desiredLocale, int choice)"
        // Tests when "if (choice < NUMBERSTYLE || choice > PLURALCURRENCYSTYLE)" is true
        for (int i = 0; i < invalid_cases.length; i++) {
            try {
                NumberFormat.getInstance((ULocale) null, invalid_cases[i]);
                errln("NumberFormat.getInstance(ULocale inLocale, int choice) was not suppose to "
                        + "return an exception for passing value of " + invalid_cases[i]);
            } catch (Exception e) {
            }
        }
    }

    /*
     * Tests the class public static abstract class NumberFormatFactory
     */
    @Test
    public void TestNumberFormatFactory() {
        /*
         * The following class allows the method public NumberFormat createFormat(Locale loc, int formatType) to be
         * tested.
         */
        class TestFactory extends NumberFormatFactory {
            @Override
            public Set<String> getSupportedLocaleNames() {
                return null;
            }

            @Override
            public NumberFormat createFormat(ULocale loc, int formatType) {
                return null;
            }
        }

        /*
         * The following class allows the method public NumberFormat createFormat(ULocale loc, int formatType) to be
         * tested.
         */
        class TestFactory1 extends NumberFormatFactory {
            @Override
            public Set<String> getSupportedLocaleNames() {
                return null;
            }

            @Override
            public NumberFormat createFormat(Locale loc, int formatType) {
                return null;
            }
        }

        TestFactory tf = new TestFactory();
        TestFactory1 tf1 = new TestFactory1();

        /*
         * Tests the method public boolean visible()
         */
        if (tf.visible() != true) {
            errln("NumberFormatFactory.visible() was suppose to return true.");
        }

        /*
         * Tests the method public NumberFormat createFormat(Locale loc, int formatType)
         */
        if (tf.createFormat(new Locale(""), 0) != null) {
            errln("NumberFormatFactory.createFormat(Locale loc, int formatType) " + "was suppose to return null");
        }

        /*
         * Tests the method public NumberFormat createFormat(ULocale loc, int formatType)
         */
        if (tf1.createFormat(new ULocale(""), 0) != null) {
            errln("NumberFormatFactory.createFormat(ULocale loc, int formatType) " + "was suppose to return null");
        }
    }

    /*
     * Tests the class public static abstract class SimpleNumberFormatFactory extends NumberFormatFactory
     */
    @Test
    public void TestSimpleNumberFormatFactory() {
        class TestSimpleNumberFormatFactory extends SimpleNumberFormatFactory {
            /*
             * Tests the method public SimpleNumberFormatFactory(Locale locale)
             */
            TestSimpleNumberFormatFactory() {
                super(new Locale(""));
            }
        }
        @SuppressWarnings("unused")
        TestSimpleNumberFormatFactory tsnff = new TestSimpleNumberFormatFactory();
    }

    /*
     * Tests the method public static ULocale[] getAvailableLocales()
     */
    @SuppressWarnings("static-access")
    @Test
    public void TestGetAvailableLocales() {
        // Tests when "if (shim == null)" is true
        @SuppressWarnings("serial")
        class TestGetAvailableLocales extends NumberFormat {
            @Override
            public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) {
                return null;
            }

            @Override
            public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos) {
                return null;
            }

            @Override
            public StringBuffer format(BigInteger number, StringBuffer toAppendTo, FieldPosition pos) {
                return null;
            }

            @Override
            public StringBuffer format(java.math.BigDecimal number, StringBuffer toAppendTo, FieldPosition pos) {
                return null;
            }

            @Override
            public StringBuffer format(BigDecimal number, StringBuffer toAppendTo, FieldPosition pos) {
                return null;
            }

            @Override
            public Number parse(String text, ParsePosition parsePosition) {
                return null;
            }
        }

        try {
            TestGetAvailableLocales test = new TestGetAvailableLocales();
            test.getAvailableLocales();
        } catch (Exception e) {
            errln("NumberFormat.getAvailableLocales() was not suppose to "
                    + "return an exception when getting getting available locales.");
        }
    }

    /*
     * Tests the method public void setMinimumIntegerDigits(int newValue)
     */
    @Test
    public void TestSetMinimumIntegerDigits() {
        NumberFormat nf = NumberFormat.getInstance();
        // For valid array, it is displayed as {min value, max value}
        // Tests when "if (minimumIntegerDigits > maximumIntegerDigits)" is true
        int[][] cases = { { -1, 0 }, { 0, 1 }, { 1, 0 }, { 2, 0 }, { 2, 1 }, { 10, 0 } };
        int[] expectedMax = { 1, 1, 0, 0, 1, 0 };
        if (cases.length != expectedMax.length) {
            errln("Can't continue test case method TestSetMinimumIntegerDigits "
                    + "since the test case arrays are unequal.");
        } else {
            for (int i = 0; i < cases.length; i++) {
                nf.setMinimumIntegerDigits(cases[i][0]);
                nf.setMaximumIntegerDigits(cases[i][1]);
                if (nf.getMaximumIntegerDigits() != expectedMax[i]) {
                    errln("NumberFormat.setMinimumIntegerDigits(int newValue "
                            + "did not return an expected result for parameter " + cases[i][0] + " and " + cases[i][1]
                                    + " and expected " + expectedMax[i] + " but got " + nf.getMaximumIntegerDigits());
                }
            }
        }
    }

    /*
     * Tests the method public int getRoundingMode() public void setRoundingMode(int roundingMode)
     */
    @Test
    public void TestRoundingMode() {
        @SuppressWarnings("serial")
        class TestRoundingMode extends NumberFormat {
            @Override
            public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) {
                return null;
            }

            @Override
            public StringBuffer format(long number, StringBuffer toAppendTo, FieldPosition pos) {
                return null;
            }

            @Override
            public StringBuffer format(BigInteger number, StringBuffer toAppendTo, FieldPosition pos) {
                return null;
            }

            @Override
            public StringBuffer format(java.math.BigDecimal number, StringBuffer toAppendTo, FieldPosition pos) {
                return null;
            }

            @Override
            public StringBuffer format(BigDecimal number, StringBuffer toAppendTo, FieldPosition pos) {
                return null;
            }

            @Override
            public Number parse(String text, ParsePosition parsePosition) {
                return null;
            }
        }
        TestRoundingMode tgrm = new TestRoundingMode();

        // Tests the function 'public void setRoundingMode(int roundingMode)'
        try {
            tgrm.setRoundingMode(0);
            errln("NumberFormat.setRoundingMode(int) was suppose to return an exception");
        } catch (Exception e) {
        }

        // Tests the function 'public int getRoundingMode()'
        try {
            tgrm.getRoundingMode();
            errln("NumberFormat.getRoundingMode() was suppose to return an exception");
        } catch (Exception e) {
        }
    }

    /*
     * Testing lenient decimal/grouping separator parsing
     */
    @Test
    public void TestLenientSymbolParsing() {
        DecimalFormat fmt = new DecimalFormat();
        DecimalFormatSymbols sym = new DecimalFormatSymbols();

        expect(fmt, "12\u300234", 12.34);

        // Ticket#7345 - case 1
        // Even strict parsing, the decimal separator set in the symbols
        // should be successfully parsed.

        sym.setDecimalSeparator('\u3002');

        // non-strict
        fmt.setDecimalFormatSymbols(sym);

        // strict - failed before the fix for #7345
        fmt.setParseStrict(true);
        expect(fmt, "23\u300245", 23.45);
        fmt.setParseStrict(false);


        // Ticket#7345 - case 2
        // Decimal separator variants other than DecimalFormatSymbols.decimalSeparator
        // should not hide the grouping separator DecimalFormatSymbols.groupingSeparator.
        sym.setDecimalSeparator('.');
        sym.setGroupingSeparator(',');
        fmt.setDecimalFormatSymbols(sym);

        expect(fmt, "1,234.56", 1234.56);

        sym.setGroupingSeparator('\uFF61');
        fmt.setDecimalFormatSymbols(sym);

        expect(fmt, "2\uFF61345.67", 2345.67);

        // Ticket#7128
        //
        sym.setGroupingSeparator(',');
        fmt.setDecimalFormatSymbols(sym);

        String skipExtSepParse = ICUConfig.get("com.ibm.icu.text.DecimalFormat.SkipExtendedSeparatorParsing", "false");
        if (skipExtSepParse.equals("true")) {
            // When the property SkipExtendedSeparatorParsing is true,
            // DecimalFormat does not use the extended equivalent separator
            // data and only uses the one in DecimalFormatSymbols.
            expect(fmt, "23 456", 23);
        } else {
            // Lenient separator parsing is enabled by default.
            // A space character below is interpreted as a
            // group separator, even ',' is used as grouping
            // separator in the symbols.
            expect(fmt, "12 345", 12345);
        }
    }

    /*
     * Testing currency driven max/min fraction digits problem
     * reported by ticket#7282
     */
    @Test
    public void TestCurrencyFractionDigits() {
        double value = 99.12345;

        // Create currency instance
        NumberFormat cfmt  = NumberFormat.getCurrencyInstance(new ULocale("ja_JP"));
        String text1 = cfmt.format(value);

        // Reset the same currency and format the test value again
        cfmt.setCurrency(cfmt.getCurrency());
        String text2 = cfmt.format(value);

        // output1 and output2 must be identical
        if (!text1.equals(text2)) {
            errln("NumberFormat.format() should return the same result - text1="
                    + text1 + " text2=" + text2);
        }
    }

    /*
     * Testing rounding to negative zero problem
     * reported by ticket#7609
     */
    @Test
    public void TestNegZeroRounding() {

        DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();
        df.setRoundingMode(MathContext.ROUND_HALF_UP);
        df.setMinimumFractionDigits(1);
        df.setMaximumFractionDigits(1);
        String text1 = df.format(-0.01);

        df.setRoundingIncrement(0.1);
        String text2 = df.format(-0.01);

        // output1 and output2 must be identical
        if (!text1.equals(text2)) {
            errln("NumberFormat.format() should return the same result - text1="
                    + text1 + " text2=" + text2);
        }

    }

    @Test
    public void TestCurrencyAmountCoverage() {
        CurrencyAmount ca, cb;

        try {
            ca = new CurrencyAmount(null, (Currency) null);
            errln("NullPointerException should have been thrown.");
        } catch (NullPointerException ex) {
        }
        try {
            ca = new CurrencyAmount(new Integer(0), (Currency) null);
            errln("NullPointerException should have been thrown.");
        } catch (NullPointerException ex) {
        }

        ca = new CurrencyAmount(new Integer(0), Currency.getInstance(new ULocale("ja_JP")));
        cb = new CurrencyAmount(new Integer(1), Currency.getInstance(new ULocale("ja_JP")));
        if (ca.equals(null)) {
            errln("Comparison should return false.");
        }
        if (!ca.equals(ca)) {
            errln("Comparision should return true.");
        }
        if (ca.equals(cb)) {
            errln("Comparison should return false.");
        }
    }

    @Test
    public void TestExponentParse() {
        ParsePosition parsePos = new ParsePosition(0);
        DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.US);
        DecimalFormat fmt = new DecimalFormat("#####", symbols);
        Number result = fmt.parse("5.06e-27", parsePos);
        if ( result.doubleValue() != 5.06E-27 || parsePos.getIndex() != 8) {
            errln("ERROR: ERROR: parse failed - expected 5.06E-27, 8; got " + result.doubleValue() + ", " + parsePos.getIndex());
        }
    }

    @Test
    public void TestExplicitParents() {
        // We use these for testing because decimal and grouping separators will be inherited from es_419
        // starting with CLDR 2.0
        String[] DATA = {
                "es", "CO", "", "1.250,75",
                "es", "ES", "", "1.250,75",
                "es", "GQ", "", "1.250,75",
                "es", "MX", "", "1,250.75",
                "es", "US", "", "1,250.75",
                "es", "VE", "", "1.250,75",

        };

        for (int i=0; i<DATA.length; i+=4) {
            Locale locale = new Locale(DATA[i], DATA[i+1], DATA[i+2]);
            NumberFormat fmt = NumberFormat.getInstance(locale);
            String s = fmt.format(1250.75);
            if (s.equals(DATA[i+3])) {
                logln("Ok: 1250.75 x " + locale + " => " + s);
            } else {
                errln("FAIL: 1250.75 x " + locale + " => " + s +
                        ", expected " + DATA[i+3]);
            }
        }
    }

    /*
     * Test case for #9240
     * ICU4J 49.1 DecimalFormat did not clone the internal object holding
     * formatted text attribute information properly. Therefore, DecimalFormat
     * created by cloning may return incorrect results or may throw an exception
     * when formatToCharacterIterator is invoked from multiple threads.
     */
    @Test
    public void TestFormatToCharacterIteratorThread() {
        final int COUNT = 10;

        DecimalFormat fmt1 = new DecimalFormat("#0");
        DecimalFormat fmt2 = (DecimalFormat)fmt1.clone();

        int[] res1 = new int[COUNT];
        int[] res2 = new int[COUNT];

        Thread t1 = new Thread(new FormatCharItrTestThread(fmt1, 1, res1));
        Thread t2 = new Thread(new FormatCharItrTestThread(fmt2, 100, res2));

        t1.start();
        t2.start();

        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            //TODO
        }

        int val1 = res1[0];
        int val2 = res2[0];

        for (int i = 0; i < COUNT; i++) {
            if (res1[i] != val1) {
                errln("Inconsistent first run limit in test thread 1");
            }
            if (res2[i] != val2) {
                errln("Inconsistent first run limit in test thread 2");
            }
        }
    }

    /*
     * This feature had to do with a limitation in DigitList.java that no longer exists in the
     * new implementation.
     *
    @Test
    public void TestParseMaxDigits() {
        DecimalFormat fmt = new DecimalFormat();
        String number = "100000000000";
        int newParseMax = number.length() - 1;

        fmt.setParseMaxDigits(-1);

        // Default value is 1000
        if (fmt.getParseMaxDigits() != 1000) {
            errln("Fail valid value checking in setParseMaxDigits.");
        }

        try {
            if (fmt.parse(number).doubleValue() == Float.POSITIVE_INFINITY) {
                errln("Got Infinity but should NOT when parsing number: " + number);
            }

            fmt.setParseMaxDigits(newParseMax);

            if (fmt.parse(number).doubleValue() != Float.POSITIVE_INFINITY) {
                errln("Did not get Infinity but should when parsing number: " + number);
            }
        } catch (ParseException ex) {

        }
    }
    */

    private static class FormatCharItrTestThread implements Runnable {
        private final NumberFormat fmt;
        private final int num;
        private final int[] result;

        FormatCharItrTestThread(NumberFormat fmt, int num, int[] result) {
            this.fmt = fmt;
            this.num = num;
            this.result = result;
        }

        @Override
        public void run() {
            for (int i = 0; i < result.length; i++) {
                AttributedCharacterIterator acitr = fmt.formatToCharacterIterator(num);
                acitr.first();
                result[i] = acitr.getRunLimit();
            }
        }
    }

    @Test
    public void TestRoundingBehavior() {
        final Object[][] TEST_CASES = {
                {
                    ULocale.US,                             // ULocale - null for default locale
                    "#.##",                                 // Pattern
                    Integer.valueOf(BigDecimal.ROUND_DOWN), // Rounding Mode or null (implicit)
                    Double.valueOf(0.0d),                   // Rounding increment, Double or BigDecimal, or null (implicit)
                    Double.valueOf(123.4567d),              // Input value, Long, Double, BigInteger or BigDecimal
                    "123.45"                                // Expected result, null for exception
                },
                {
                    ULocale.US,
                    "#.##",
                    null,
                    Double.valueOf(0.1d),
                    Double.valueOf(123.4567d),
                    "123.5"
                },
                {
                    ULocale.US,
                    "#.##",
                    Integer.valueOf(BigDecimal.ROUND_DOWN),
                    Double.valueOf(0.1d),
                    Double.valueOf(123.4567d),
                    "123.4"
                },
                {
                    ULocale.US,
                    "#.##",
                    Integer.valueOf(BigDecimal.ROUND_UNNECESSARY),
                    null,
                    Double.valueOf(123.4567d),
                    null
                },
                {
                    ULocale.US,
                    "#.##",
                    Integer.valueOf(BigDecimal.ROUND_DOWN),
                    null,
                    Long.valueOf(1234),
                    "1234"
                },
        };

        int testNum = 1;

        for (Object[] testCase : TEST_CASES) {
            // 0: locale
            // 1: pattern
            ULocale locale = testCase[0] == null ? ULocale.getDefault() : (ULocale)testCase[0];
            String pattern = (String)testCase[1];

            DecimalFormat fmt = new DecimalFormat(pattern, DecimalFormatSymbols.getInstance(locale));

            // 2: rounding mode
            Integer roundingMode = null;
            if (testCase[2] != null) {
                roundingMode = (Integer)testCase[2];
                fmt.setRoundingMode(roundingMode);
            }

            // 3: rounding increment
            if (testCase[3] != null) {
                if (testCase[3] instanceof Double) {
                    fmt.setRoundingIncrement((Double)testCase[3]);
                } else if (testCase[3] instanceof BigDecimal) {
                    fmt.setRoundingIncrement((BigDecimal)testCase[3]);
                } else if (testCase[3] instanceof java.math.BigDecimal) {
                    fmt.setRoundingIncrement((java.math.BigDecimal)testCase[3]);
                }
            }

            // 4: input number
            String s = null;
            boolean bException = false;
            try {
                s = fmt.format(testCase[4]);
            } catch (ArithmeticException e) {
                bException = true;
            }

            if (bException) {
                if (testCase[5] != null) {
                    errln("Test case #" + testNum + ": ArithmeticException was thrown.");
                }
            } else {
                if (testCase[5] == null) {
                    errln("Test case #" + testNum +
                            ": ArithmeticException must be thrown, but got formatted result: " +
                            s);
                } else {
                    assertEquals("Test case #" + testNum, testCase[5], s);
                }
            }

            testNum++;
        }
    }

    @Test
    public void TestSignificantDigits() {
        double input[] = {
                0, 0,
                123, -123,
                12345, -12345,
                123.45, -123.45,
                123.44501, -123.44501,
                0.001234, -0.001234,
                0.00000000123, -0.00000000123,
                0.0000000000000000000123, -0.0000000000000000000123,
                1.2, -1.2,
                0.0000000012344501, -0.0000000012344501,
                123445.01, -123445.01,
                12344501000000000000000000000000000.0, -12344501000000000000000000000000000.0,
        };
        String[] expected = {
                "0.00", "0.00",
                "123", "-123",
                "12345", "-12345",
                "123.45", "-123.45",
                "123.45", "-123.45",
                "0.001234", "-0.001234",
                "0.00000000123", "-0.00000000123",
                "0.0000000000000000000123", "-0.0000000000000000000123",
                "1.20", "-1.20",
                "0.0000000012345", "-0.0000000012345",
                "123450", "-123450",
                "12345000000000000000000000000000000", "-12345000000000000000000000000000000",
        };
        DecimalFormat numberFormat =
                (DecimalFormat) NumberFormat.getInstance(ULocale.US);
        numberFormat.setSignificantDigitsUsed(true);
        numberFormat.setMinimumSignificantDigits(3);
        numberFormat.setMaximumSignificantDigits(5);
        numberFormat.setGroupingUsed(false);
        for (int i = 0; i < input.length; i++) {
            assertEquals("TestSignificantDigits", expected[i], numberFormat.format(input[i]));
        }

        // Test for ICU-20063
        {
            DecimalFormat df = new DecimalFormat("0.######", DecimalFormatSymbols.getInstance(ULocale.US));
            df.setSignificantDigitsUsed(true);
            expect(df, 9.87654321, "9.87654");
            df.setMaximumSignificantDigits(3);
            expect(df, 9.87654321, "9.88");
            // setSignificantDigitsUsed with maxSig only
            df.setSignificantDigitsUsed(true);
            expect(df, 9.87654321, "9.88");
            df.setMinimumSignificantDigits(2);
            expect(df, 9, "9.0");
            // setSignificantDigitsUsed with both minSig and maxSig
            df.setSignificantDigitsUsed(true);
            expect(df, 9, "9.0");
            // setSignificantDigitsUsed to false: should revert to fraction rounding
            df.setSignificantDigitsUsed(false);
            expect(df, 9.87654321, "9.876543");
            expect(df, 9, "9");
            df.setSignificantDigitsUsed(true);
            df.setMinimumSignificantDigits(2);
            expect(df, 9.87654321, "9.87654");
            expect(df, 9, "9.0");
            // setSignificantDigitsUsed with minSig only
            df.setSignificantDigitsUsed(true);
            expect(df, 9.87654321, "9.87654");
            expect(df, 9, "9.0");
        }
    }

    @Test
    public void TestSetMaxFracAndRoundIncr() {
        class SetMxFrAndRndIncrItem {
            String descrip;
            String localeID;
            int    style;
            int    minInt;
            int    minFrac;
            int    maxFrac;
            double roundIncr;
            String expPattern;
            double valueToFmt;
            String expFormat;
             // Simple constructor
            public SetMxFrAndRndIncrItem(String desc, String loc, int stl, int mnI, int mnF, int mxF,
                                                double rdIn, String ePat, double val, String eFmt) {
                descrip = desc;
                localeID = loc;
                style = stl;
                minInt = mnI;
                minFrac = mnF;
                maxFrac = mxF;
                roundIncr = rdIn;
                expPattern = ePat;
                valueToFmt = val;
                expFormat = eFmt ;
            }
        };

        final SetMxFrAndRndIncrItem[] items = {
            //                         descrip                     locale   style                      mnI mnF mxF rdInc   expPat        value  expFmt
            new SetMxFrAndRndIncrItem( "01 en_US DEC 1/0/3/0.0",    "en_US", NumberFormat.NUMBERSTYLE,  1,  0,  3, 0.0,    "#,##0.###",  0.128, "0.128" ),
            new SetMxFrAndRndIncrItem( "02 en_US DEC 1/0/1/0.0",    "en_US", NumberFormat.NUMBERSTYLE,  1,  0,  1, 0.0,    "#,##0.#",    0.128, "0.1"   ),
            new SetMxFrAndRndIncrItem( "03 en_US DEC 1/0/1/0.01",   "en_US", NumberFormat.NUMBERSTYLE,  1,  0,  1, 0.01,   "#,##0.#",    0.128, "0.1"   ),
            new SetMxFrAndRndIncrItem( "04 en_US DEC 1/1/1/0.01",   "en_US", NumberFormat.NUMBERSTYLE,  1,  1,  1, 0.01,   "#,##0.0",    0.128, "0.1"   ),
            new SetMxFrAndRndIncrItem( "05 en_US DEC 1/0/1/0.1",    "en_US", NumberFormat.NUMBERSTYLE,  1,  0,  1, 0.1,    "#,##0.1",    0.128, "0.1"   ), // use incr
            new SetMxFrAndRndIncrItem( "06 en_US DEC 1/1/1/0.1",    "en_US", NumberFormat.NUMBERSTYLE,  1,  1,  1, 0.1,    "#,##0.1",    0.128, "0.1"   ), // use incr

            new SetMxFrAndRndIncrItem( "10 en_US DEC 1/0/1/0.02",   "en_US", NumberFormat.NUMBERSTYLE,  1,  0,  1, 0.02,   "#,##0.#",    0.128, "0.1"   ),
            new SetMxFrAndRndIncrItem( "11 en_US DEC 1/0/2/0.02",   "en_US", NumberFormat.NUMBERSTYLE,  1,  0,  2, 0.02,   "#,##0.02",   0.128, "0.12"  ), // use incr
            new SetMxFrAndRndIncrItem( "12 en_US DEC 1/0/3/0.02",   "en_US", NumberFormat.NUMBERSTYLE,  1,  0,  3, 0.02,   "#,##0.02#",  0.128, "0.12"  ), // use incr
            new SetMxFrAndRndIncrItem( "13 en_US DEC 1/1/1/0.02",   "en_US", NumberFormat.NUMBERSTYLE,  1,  1,  1, 0.02,   "#,##0.0",    0.128, "0.1"   ),
            new SetMxFrAndRndIncrItem( "14 en_US DEC 1/1/2/0.02",   "en_US", NumberFormat.NUMBERSTYLE,  1,  1,  2, 0.02,   "#,##0.02",   0.128, "0.12"  ), // use incr
            new SetMxFrAndRndIncrItem( "15 en_US DEC 1/1/3/0.02",   "en_US", NumberFormat.NUMBERSTYLE,  1,  1,  3, 0.02,   "#,##0.02#",  0.128, "0.12"  ), // use incr
            new SetMxFrAndRndIncrItem( "16 en_US DEC 1/2/2/0.02",   "en_US", NumberFormat.NUMBERSTYLE,  1,  2,  2, 0.02,   "#,##0.02",   0.128, "0.12"  ), // use incr
            new SetMxFrAndRndIncrItem( "17 en_US DEC 1/2/3/0.02",   "en_US", NumberFormat.NUMBERSTYLE,  1,  2,  3, 0.02,   "#,##0.02#",  0.128, "0.12"  ), // use incr
            new SetMxFrAndRndIncrItem( "18 en_US DEC 1/3/3/0.02",   "en_US", NumberFormat.NUMBERSTYLE,  1,  3,  3, 0.02,   "#,##0.020",  0.128, "0.12"  ), // use incr; expFmt != ICU4C

            new SetMxFrAndRndIncrItem( "20 en_US DEC 1/1/1/0.0075", "en_US", NumberFormat.NUMBERSTYLE,  1,  1,  1, 0.0075, "#,##0.0",    0.019, "0.0"    ),
            new SetMxFrAndRndIncrItem( "21 en_US DEC 1/1/2/0.0075", "en_US", NumberFormat.NUMBERSTYLE,  1,  1,  2, 0.0075, "#,##0.0075", 0.004, "0.0075" ), // use incr
            new SetMxFrAndRndIncrItem( "22 en_US DEC 1/1/2/0.0075", "en_US", NumberFormat.NUMBERSTYLE,  1,  1,  2, 0.0075, "#,##0.0075", 0.019, "0.0225" ), // use incr
            new SetMxFrAndRndIncrItem( "23 en_US DEC 1/1/3/0.0075", "en_US", NumberFormat.NUMBERSTYLE,  1,  1,  3, 0.0075, "#,##0.0075", 0.004, "0.0075" ), // use incr
            new SetMxFrAndRndIncrItem( "24 en_US DEC 1/1/3/0.0075", "en_US", NumberFormat.NUMBERSTYLE,  1,  1,  3, 0.0075, "#,##0.0075", 0.019, "0.0225" ), // use incr
            new SetMxFrAndRndIncrItem( "25 en_US DEC 1/2/2/0.0075", "en_US", NumberFormat.NUMBERSTYLE,  1,  2,  2, 0.0075, "#,##0.0075", 0.004, "0.0075" ), // use incr
            new SetMxFrAndRndIncrItem( "26 en_US DEC 1/2/2/0.0075", "en_US", NumberFormat.NUMBERSTYLE,  1,  2,  2, 0.0075, "#,##0.0075", 0.019, "0.0225" ), // use incr
            new SetMxFrAndRndIncrItem( "27 en_US DEC 1/2/3/0.0075", "en_US", NumberFormat.NUMBERSTYLE,  1,  2,  3, 0.0075, "#,##0.0075", 0.004, "0.0075" ), // use incr
            new SetMxFrAndRndIncrItem( "28 en_US DEC 1/2/3/0.0075", "en_US", NumberFormat.NUMBERSTYLE,  1,  2,  3, 0.0075, "#,##0.0075", 0.019, "0.0225" ), // use incr
            new SetMxFrAndRndIncrItem( "29 en_US DEC 1/3/3/0.0075", "en_US", NumberFormat.NUMBERSTYLE,  1,  3,  3, 0.0075, "#,##0.0075", 0.004, "0.0075" ), // use incr
            new SetMxFrAndRndIncrItem( "2A en_US DEC 1/3/3/0.0075", "en_US", NumberFormat.NUMBERSTYLE,  1,  3,  3, 0.0075, "#,##0.0075", 0.019, "0.0225" ), // use incr
        };

        for (SetMxFrAndRndIncrItem item: items) {
            ULocale locale = new ULocale(item.localeID);
            DecimalFormat df = (DecimalFormat)NumberFormat.getInstance(locale, item.style);
            df.setMinimumIntegerDigits(item.minInt);
            df.setMinimumFractionDigits(item.minFrac);
            df.setMaximumFractionDigits(item.maxFrac);
            df.setRoundingIncrement(item.roundIncr);

            boolean roundIncrUsed = (item.roundIncr != 0 &&
                    !PatternStringUtils.ignoreRoundingIncrement(java.math.BigDecimal.valueOf(item.roundIncr),item.maxFrac));
            int fracForRoundIncr = 0;
            if (roundIncrUsed) {
                double  testIncr = item.roundIncr;
                for (; testIncr > ((int)testIncr); testIncr *= 10.0, fracForRoundIncr++);
            }

            int minInt = df.getMinimumIntegerDigits();
            if (minInt != item.minInt) {
                errln("test " + item.descrip + ": getMinimumIntegerDigits, expected " + item.minInt + ", got " + minInt);
            }
            int minFrac = df.getMinimumFractionDigits();
            int expMinFrac = (roundIncrUsed)? fracForRoundIncr: item.minFrac;
            if (minFrac != expMinFrac) {
                errln("test " + item.descrip + ": getMinimumFractionDigits, expected " + expMinFrac + ", got " + minFrac);
            }
            int maxFrac = df.getMaximumFractionDigits();
            int expMaxFrac = (roundIncrUsed)? fracForRoundIncr: item.maxFrac;
            if (maxFrac != expMaxFrac) {
                errln("test " + item.descrip + ": getMaximumFractionDigits, expected " + expMaxFrac + ", got " + maxFrac);
            }
            java.math.BigDecimal bigdec = df.getRoundingIncrement(); // why doesn't this return com.ibm.icu.math.BigDecimal?
            double roundIncr = (bigdec != null)? bigdec.doubleValue(): 0.0;
            double expRoundIncr = (roundIncrUsed)? item.roundIncr: 0.0;
            if (roundIncr != expRoundIncr) {
                errln("test " + item.descrip + ": getRoundingIncrement, expected " + expRoundIncr + ", got " + roundIncr);
            }

            String getPattern = df.toPattern();
            if (!getPattern.equals(item.expPattern)) {
                errln("test " + item.descrip + ": toPattern, expected " + item.expPattern + ", got " + getPattern);
            }
            String getFormat = df.format(item.valueToFmt);
            if (!getFormat.equals(item.expFormat)) {
                errln("test " + item.descrip + ": format, expected " + item.expFormat + ", got " + getFormat);
            }
        }
    }

    @Test
    public void TestMinIntMinFracZero() {
        class TestMinIntMinFracItem {
            double value;;
            String expDecFmt;
            String expCurFmt;
             // Simple constructor
            public TestMinIntMinFracItem(double valueIn, String expDecFmtIn, String expCurFmtIn) {
                value = valueIn;
                expDecFmt = expDecFmtIn;
                expCurFmt = expCurFmtIn;
            }
        };

        final TestMinIntMinFracItem[] items = {
            //                              decFmt curFmt
            new TestMinIntMinFracItem( 10.0, "10", "$10" ),
            new TestMinIntMinFracItem(  0.9, ".9", "$.9" ),
            new TestMinIntMinFracItem(  0.0, "0",  "$0"  ),
        };
        int minInt, minFrac;

        NumberFormat decFormat = NumberFormat.getInstance(ULocale.US, NumberFormat.NUMBERSTYLE);
        decFormat.setMinimumIntegerDigits(0);
        decFormat.setMinimumFractionDigits(0);
        minInt = decFormat.getMinimumIntegerDigits();
        minFrac = decFormat.getMinimumFractionDigits();
        if (minInt != 0 || minFrac != 0) {
            errln("after setting DECIMAL  minInt=minFrac=0, get minInt " + minInt + ", minFrac " + minFrac);
        }
        String decPattern = ((DecimalFormat)decFormat).toPattern();
        if (decPattern.length() < 3 || decPattern.indexOf("#.#")< 0) {
            errln("after setting DECIMAL  minInt=minFrac=0, expect pattern to contain \"#.#\", but get " + decPattern);
        }

        NumberFormat curFormat = NumberFormat.getInstance(ULocale.US, NumberFormat.CURRENCYSTYLE);
        curFormat.setMinimumIntegerDigits(0);
        curFormat.setMinimumFractionDigits(0);
        minInt = curFormat.getMinimumIntegerDigits();
        minFrac = curFormat.getMinimumFractionDigits();
        if (minInt != 0 || minFrac != 0) {
            errln("after setting CURRENCY minInt=minFrac=0, get minInt " + minInt + ", minFrac " + minFrac);
        }

        for (TestMinIntMinFracItem item: items) {
            String decString = decFormat.format(item.value);
            if (!decString.equals(item.expDecFmt)) {
                errln("format DECIMAL  value " + item.value + ", expected \"" + item.expDecFmt + "\", got \"" + decString + "\"");
            }
            String curString = curFormat.format(item.value);
            if (!curString.equals(item.expCurFmt)) {
                errln("format CURRENCY value " + item.value + ", expected \"" + item.expCurFmt + "\", got \"" + curString + "\"");
            }
        }
    }

    @Test
    public void TestBug9936() {
        DecimalFormat numberFormat =
                (DecimalFormat) NumberFormat.getInstance(ULocale.US);
        assertFalse("", numberFormat.areSignificantDigitsUsed());

        numberFormat.setSignificantDigitsUsed(true);
        assertTrue("", numberFormat.areSignificantDigitsUsed());

        numberFormat.setSignificantDigitsUsed(false);
        assertFalse("", numberFormat.areSignificantDigitsUsed());

        numberFormat.setMinimumSignificantDigits(3);
        assertTrue("", numberFormat.areSignificantDigitsUsed());

        numberFormat.setSignificantDigitsUsed(false);
        numberFormat.setMaximumSignificantDigits(6);
        assertTrue("", numberFormat.areSignificantDigitsUsed());
    }

    @Test
    public void TestShowZero() {
        DecimalFormat numberFormat =
                (DecimalFormat) NumberFormat.getInstance(ULocale.US);
        numberFormat.setSignificantDigitsUsed(true);
        numberFormat.setMaximumSignificantDigits(3);
        assertEquals("TestShowZero", "0", numberFormat.format(0.0));
    }

    @Test
    public void TestCurrencyPlurals() {
        String[][] tests = {
                {"en", "USD", "1", "1 US dollar"},
                {"en", "USD", "1.0", "1.0 US dollars"},
                {"en", "USD", "1.00", "1.00 US dollars"},
                {"en", "USD", "1.99", "1.99 US dollars"},
                {"en", "AUD", "1", "1 Australian dollar"},
                {"en", "AUD", "1.00", "1.00 Australian dollars"},
                {"sl", "USD", "1", "1 ameri\u0161ki dolar"},
                {"sl", "USD", "2", "2 ameri\u0161ka dolarja"},
                {"sl", "USD", "3", "3 ameri\u0161ki dolarji"},
                {"sl", "USD", "5", "5 ameriških dolarjev"},
                {"fr", "USD", "1.99", "1,99 dollar des États-Unis"},
                {"ru", "RUB", "1", "1 \u0440\u043E\u0441\u0441\u0438\u0439\u0441\u043A\u0438\u0439 \u0440\u0443\u0431\u043B\u044C"},
                {"ru", "RUB", "2", "2 \u0440\u043E\u0441\u0441\u0438\u0439\u0441\u043A\u0438\u0445 \u0440\u0443\u0431\u043B\u044F"},
                {"ru", "RUB", "5", "5 \u0440\u043E\u0441\u0441\u0438\u0439\u0441\u043A\u0438\u0445 \u0440\u0443\u0431\u043B\u0435\u0439"},
        };
        for (String test[] : tests) {
            DecimalFormat numberFormat = (DecimalFormat) DecimalFormat.getInstance(new ULocale(test[0]), NumberFormat.PLURALCURRENCYSTYLE);
            numberFormat.setCurrency(Currency.getInstance(test[1]));
            double number = Double.parseDouble(test[2]);
            int dotPos = test[2].indexOf('.');
            int decimals = dotPos < 0 ? 0 : test[2].length() - dotPos - 1;
            int digits = dotPos < 0 ? test[2].length() : test[2].length() - 1;
            numberFormat.setMaximumFractionDigits(decimals);
            numberFormat.setMinimumFractionDigits(decimals);
            String actual = numberFormat.format(number);
            assertEquals(test[0] + "\t" + test[1] + "\t" + test[2], test[3], actual);
            numberFormat.setMaximumSignificantDigits(digits);
            numberFormat.setMinimumSignificantDigits(digits);
            actual = numberFormat.format(number);
            assertEquals(test[0] + "\t" + test[1] + "\t" + test[2], test[3], actual);
        }
    }

    @Test
    public void TestCustomCurrencySignAndSeparator() {
        DecimalFormatSymbols custom = new DecimalFormatSymbols(ULocale.US);

        custom.setCurrencySymbol("*");
        custom.setMonetaryGroupingSeparator('^');
        custom.setMonetaryDecimalSeparator(':');

        DecimalFormat fmt = new DecimalFormat("\u00A4 #,##0.00", custom);

        final String numstr = "* 1^234:56";
        expect2(fmt, 1234.56, numstr);
    }

    @Test
    public void TestParseSignsAndMarks() {
        class SignsAndMarksItem {
            public String locale;
            public boolean lenient;
            public String numString;
            public double value;
             // Simple constructor
            public SignsAndMarksItem(String loc, boolean lnt, String numStr, double val) {
                locale = loc;
                lenient = lnt;
                numString = numStr;
                value = val;
            }
        };
        final SignsAndMarksItem[] items = {
            // *** Note, ICU4J lenient number parsing does not handle arbitrary whitespace, but can
            // treat some whitespace as a grouping separator. The cases marked *** below depend
            // on isGroupingUsed() being set for the locale, which in turn depends on grouping
            // separators being present in the decimalFormat pattern for the locale (& num sys).
            //
            //                    locale                lenient numString                               value
            new SignsAndMarksItem("en",                 false,  "12",                                    12 ),
            new SignsAndMarksItem("en",                 true,   "12",                                    12 ),
            new SignsAndMarksItem("en",                 false,  "-23",                                  -23 ),
            new SignsAndMarksItem("en",                 true,   "-23",                                  -23 ),
            new SignsAndMarksItem("en",                 true,   "- 23",                                 -23 ), // ***
            new SignsAndMarksItem("en",                 false,  "\u200E-23",                            -23 ),
            new SignsAndMarksItem("en",                 true,   "\u200E-23",                            -23 ),
            new SignsAndMarksItem("en",                 true,   "\u200E- 23",                           -23 ), // ***

            new SignsAndMarksItem("en@numbers=arab",    false,  "\u0663\u0664",                          34 ),
            new SignsAndMarksItem("en@numbers=arab",    true,   "\u0663\u0664",                          34 ),
            new SignsAndMarksItem("en@numbers=arab",    false,  "-\u0664\u0665",                        -45 ),
            new SignsAndMarksItem("en@numbers=arab",    true,   "-\u0664\u0665",                        -45 ),
            new SignsAndMarksItem("en@numbers=arab",    true,   "- \u0664\u0665",                       -45 ), // ***
            new SignsAndMarksItem("en@numbers=arab",    false,  "\u200F-\u0664\u0665",                  -45 ),
            new SignsAndMarksItem("en@numbers=arab",    true,   "\u200F-\u0664\u0665",                  -45 ),
            new SignsAndMarksItem("en@numbers=arab",    true,   "\u200F- \u0664\u0665",                 -45 ), // ***

            new SignsAndMarksItem("en@numbers=arabext", false,  "\u06F5\u06F6",                          56 ),
            new SignsAndMarksItem("en@numbers=arabext", true,   "\u06F5\u06F6",                          56 ),
            new SignsAndMarksItem("en@numbers=arabext", false,  "-\u06F6\u06F7",                        -67 ),
            new SignsAndMarksItem("en@numbers=arabext", true,   "-\u06F6\u06F7",                        -67 ),
            new SignsAndMarksItem("en@numbers=arabext", true,   "- \u06F6\u06F7",                       -67 ), // ***
            new SignsAndMarksItem("en@numbers=arabext", false,  "\u200E-\u200E\u06F6\u06F7",            -67 ),
            new SignsAndMarksItem("en@numbers=arabext", true,   "\u200E-\u200E\u06F6\u06F7",            -67 ),
            new SignsAndMarksItem("en@numbers=arabext", true,   "\u200E-\u200E \u06F6\u06F7",           -67 ), // ***

            new SignsAndMarksItem("he",                 false,  "12",                                    12 ),
            new SignsAndMarksItem("he",                 true,   "12",                                    12 ),
            new SignsAndMarksItem("he",                 false,  "-23",                                  -23 ),
            new SignsAndMarksItem("he",                 true,   "-23",                                  -23 ),
            new SignsAndMarksItem("he",                 true,   "- 23",                                 -23 ), // ***
            new SignsAndMarksItem("he",                 false,  "\u200E-23",                            -23 ),
            new SignsAndMarksItem("he",                 true,   "\u200E-23",                            -23 ),
            new SignsAndMarksItem("he",                 true,   "\u200E- 23",                           -23 ), // ***

            new SignsAndMarksItem("ar",                 false,  "\u0663\u0664",                          34 ),
            new SignsAndMarksItem("ar",                 true,   "\u0663\u0664",                          34 ),
            new SignsAndMarksItem("ar",                 false,  "-\u0664\u0665",                        -45 ),
            new SignsAndMarksItem("ar",                 true,   "-\u0664\u0665",                        -45 ),
            new SignsAndMarksItem("ar",                 true,   "- \u0664\u0665",                       -45 ), // ***
            new SignsAndMarksItem("ar",                 false,  "\u200F-\u0664\u0665",                  -45 ),
            new SignsAndMarksItem("ar",                 true,   "\u200F-\u0664\u0665",                  -45 ),
            new SignsAndMarksItem("ar",                 true,   "\u200F- \u0664\u0665",                 -45 ), // ***

            new SignsAndMarksItem("ar_MA",              false,  "12",                                    12 ),
            new SignsAndMarksItem("ar_MA",              true,   "12",                                    12 ),
            new SignsAndMarksItem("ar_MA",              false,  "-23",                                  -23 ),
            new SignsAndMarksItem("ar_MA",              true,   "-23",                                  -23 ),
            new SignsAndMarksItem("ar_MA",              true,   "- 23",                                 -23 ), // ***
            new SignsAndMarksItem("ar_MA",              false,  "\u200E-23",                            -23 ),
            new SignsAndMarksItem("ar_MA",              true,   "\u200E-23",                            -23 ),
            new SignsAndMarksItem("ar_MA",              true,   "\u200E- 23",                           -23 ), // ***

            new SignsAndMarksItem("fa",                 false,  "\u06F5\u06F6",                          56 ),
            new SignsAndMarksItem("fa",                 true,   "\u06F5\u06F6",                          56 ),
            new SignsAndMarksItem("fa",                 false,  "\u2212\u06F6\u06F7",                   -67 ),
            new SignsAndMarksItem("fa",                 true,   "\u2212\u06F6\u06F7",                   -67 ),
            new SignsAndMarksItem("fa",                 true,   "\u2212 \u06F6\u06F7",                  -67 ), // ***
            new SignsAndMarksItem("fa",                 false,  "\u200E\u2212\u200E\u06F6\u06F7",       -67 ),
            new SignsAndMarksItem("fa",                 true,   "\u200E\u2212\u200E\u06F6\u06F7",       -67 ),
            new SignsAndMarksItem("fa",                 true,   "\u200E\u2212\u200E \u06F6\u06F7",      -67 ), // ***

            new SignsAndMarksItem("ps",                 false,  "\u06F5\u06F6",                          56 ),
            new SignsAndMarksItem("ps",                 true,   "\u06F5\u06F6",                          56 ),
            new SignsAndMarksItem("ps",                 false,  "-\u06F6\u06F7",                        -67 ),
            new SignsAndMarksItem("ps",                 true,   "-\u06F6\u06F7",                        -67 ),
            new SignsAndMarksItem("ps",                 true,   "- \u06F6\u06F7",                       -67 ), // ***
            new SignsAndMarksItem("ps",                 false,  "\u200E-\u200E\u06F6\u06F7",            -67 ),
            new SignsAndMarksItem("ps",                 true,   "\u200E-\u200E\u06F6\u06F7",            -67 ),
            new SignsAndMarksItem("ps",                 true,   "\u200E-\u200E \u06F6\u06F7",           -67 ), // ***
            new SignsAndMarksItem("ps",                 false,  "-\u200E\u06F6\u06F7",                  -67 ),
            new SignsAndMarksItem("ps",                 true,   "-\u200E\u06F6\u06F7",                  -67 ),
            new SignsAndMarksItem("ps",                 true,   "-\u200E \u06F6\u06F7",                 -67 ), // ***
        };
        for (SignsAndMarksItem item: items) {
            ULocale locale = new ULocale(item.locale);
            NumberFormat numfmt = NumberFormat.getInstance(locale);
            if (numfmt != null) {
                numfmt.setParseStrict(!item.lenient);
                ParsePosition ppos = new ParsePosition(0);
                Number num = numfmt.parse(item.numString, ppos);
                if (num != null && ppos.getIndex() == item.numString.length()) {
                    double parsedValue = num.doubleValue();
                    if (parsedValue != item.value) {
                        errln("FAIL: locale " + item.locale + ", lenient " + item.lenient + ", parse of \"" + item.numString + "\" gives value " + parsedValue);
                    }
                } else {
                    errln("FAIL: locale " + item.locale + ", lenient " + item.lenient + ", parse of \"" + item.numString + "\" gives position " + ppos.getIndex());
                }
            } else {
                errln("FAIL: NumberFormat.getInstance for locale " + item.locale);
            }
        }
    }

    @Test
    public void TestContext() {
        // just a minimal sanity check for now
        NumberFormat nfmt = NumberFormat.getInstance();
        DisplayContext context = nfmt.getContext(DisplayContext.Type.CAPITALIZATION);
        if (context != DisplayContext.CAPITALIZATION_NONE) {
            errln("FAIL: Initial NumberFormat.getContext() is not CAPITALIZATION_NONE");
        }
        nfmt.setContext(DisplayContext.CAPITALIZATION_FOR_STANDALONE);
        context = nfmt.getContext(DisplayContext.Type.CAPITALIZATION);
        if (context != DisplayContext.CAPITALIZATION_FOR_STANDALONE) {
            errln("FAIL: NumberFormat.getContext() does not return the value set, CAPITALIZATION_FOR_STANDALONE");
        }
    }

    @Test
    public void TestAccountingCurrency() {
        String[][] tests = {
                //locale              num         curr fmt per loc     curr std fmt         curr acct fmt        rt
                {"en_US",             "1234.5",   "$1,234.50",         "$1,234.50",         "$1,234.50",         "true"},
                {"en_US@cf=account",  "1234.5",   "$1,234.50",         "$1,234.50",         "$1,234.50",         "true"},
                {"en_US",             "-1234.5",  "-$1,234.50",        "-$1,234.50",        "($1,234.50)",       "true"},
                {"en_US@cf=standard", "-1234.5",  "-$1,234.50",        "-$1,234.50",        "($1,234.50)",       "true"},
                {"en_US@cf=account",  "-1234.5",  "($1,234.50)",       "-$1,234.50",        "($1,234.50)",       "true"},
                {"en_US",             "0",        "$0.00",             "$0.00",             "$0.00",             "true"},
                {"en_US",             "-0.2",     "-$0.20",            "-$0.20",            "($0.20)",           "true"},
                {"en_US@cf=standard", "-0.2",     "-$0.20",            "-$0.20",            "($0.20)",           "true"},
                {"en_US@cf=account",  "-0.2",     "($0.20)",           "-$0.20",            "($0.20)",           "true"},
                {"ja_JP",             "10000",    "￥10,000",          "￥10,000",          "￥10,000",          "true" },
                {"ja_JP",             "-1000.5",  "-￥1,000",          "-￥1,000",          "(￥1,000)",         "false"},
                {"ja_JP@cf=account",  "-1000.5",  "(￥1,000)",         "-￥1,000",          "(￥1,000)",         "false"},
                {"de_DE",             "-23456.7", "-23.456,70\u00A0€", "-23.456,70\u00A0€", "-23.456,70\u00A0€", "true" },
                {"en_ID",             "1234.5",   "IDR 1,234.50",      "IDR 1,234.50",      "IDR 1,234.50",      "true"},
                {"en_ID@cf=account",  "1234.5",   "IDR 1,234.50",      "IDR 1,234.50",      "IDR 1,234.50",      "true"},
                {"en_ID@cf=standard", "1234.5",   "IDR 1,234.50",      "IDR 1,234.50",      "IDR 1,234.50",      "true"},
                {"en_ID",             "-1234.5",  "-IDR 1,234.50",     "-IDR 1,234.50",     "(IDR 1,234.50)",    "true"},
                {"en_ID@cf=account",  "-1234.5",  "(IDR 1,234.50)",    "-IDR 1,234.50",     "(IDR 1,234.50)",    "true"},
                {"en_ID@cf=standard", "-1234.5",  "-IDR 1,234.50",     "-IDR 1,234.50",     "(IDR 1,234.50)",    "true"},
                {"sh_ME",             "1234.5",   "1.234,50 €",        "1.234,50 €",        "1.234,50 €",        "true"},
                {"sh_ME@cf=account",  "1234.5",   "1.234,50 €",        "1.234,50 €",        "1.234,50 €",        "true"},
                {"sh_ME@cf=standard", "1234.5",   "1.234,50 €",        "1.234,50 €",        "1.234,50 €",        "true"},
                {"sh_ME",             "-1234.5",  "-1.234,50 €",       "-1.234,50 €",       "(1.234,50 €)",      "true"},
                {"sh_ME@cf=account",  "-1234.5",  "(1.234,50 €)",      "-1.234,50 €",       "(1.234,50 €)",      "true"},
                {"sh_ME@cf=standard", "-1234.5",  "-1.234,50 €",       "-1.234,50 €",       "(1.234,50 €)",      "true"},
        };
        for (String[] data : tests) {
            ULocale loc = new ULocale(data[0]);
            double num = Double.parseDouble(data[1]);
            String fmtPerLocExpected   = data[2];
            String fmtStandardExpected = data[3];
            String fmtAccountExpected  = data[4];
            boolean rt = Boolean.parseBoolean(data[5]);

            NumberFormat fmtPerLoc = NumberFormat.getInstance(loc, NumberFormat.CURRENCYSTYLE);
            expect(fmtPerLoc, num, fmtPerLocExpected, rt);

            NumberFormat fmtStandard = NumberFormat.getInstance(loc, NumberFormat.STANDARDCURRENCYSTYLE);
            expect(fmtStandard, num, fmtStandardExpected, rt);

            NumberFormat fmtAccount = NumberFormat.getInstance(loc, NumberFormat.ACCOUNTINGCURRENCYSTYLE);
            expect(fmtAccount, num, fmtAccountExpected, rt);
        }
    }

    /**
     * en_ID/sh_ME uses language only locales en/sh which requires NumberFormatServiceShim to fill in the currency, but
     * prior to ICU-20631, currency was not filled in for accounting, cash and standard, so currency placeholder was
     * used instead of the desired locale's currency.
     */
    @Test
    public void TestCurrencyFormatForMissingLocale() {
        ULocale loc = new ULocale("sh_ME");
        Currency cur = Currency.getInstance(loc);
        NumberFormat curFmt = NumberFormat.getInstance(loc, NumberFormat.CURRENCYSTYLE);
        assertNotNull("NumberFormat is missing currency instance for CURRENCYSTYLE", curFmt.getCurrency());
        assertEquals("Currency instance is not for the desired locale for CURRENCYSTYLE", cur, curFmt.getCurrency());
        assertEquals("NumberFormat format outputs wrong value for CURRENCYSTYLE", "-1.234,50 €", curFmt.format(-1234.5d));
        NumberFormat accFmt = NumberFormat.getInstance(loc, NumberFormat.ACCOUNTINGCURRENCYSTYLE);
        assertNotNull("NumberFormat is missing currency instance for ACCOUNTINGCURRENCYSTYLE", accFmt.getCurrency());
        assertEquals("Currency instance is not for the desired locale for ACCOUNTINGCURRENCYSTYLE", cur, accFmt.getCurrency());
        assertEquals("NumberFormat format outputs wrong value for ACCOUNTINGCURRENCYSTYLE", "(1.234,50 €)", accFmt.format(-1234.5d));
        NumberFormat cashFmt = NumberFormat.getInstance(loc, NumberFormat.CASHCURRENCYSTYLE);
        assertNotNull("NumberFormat is missing currency instance for CASHCURRENCYSTYLE", cashFmt.getCurrency());
        assertEquals("Currency instance is not for the desired locale for CASHCURRENCYSTYLE", cur, cashFmt.getCurrency());
        assertEquals("NumberFormat format outputs wrong value for CASHCURRENCYSTYLE", "-1.234,50 €", cashFmt.format(-1234.5d));
        NumberFormat stdFmt = NumberFormat.getInstance(loc, NumberFormat.STANDARDCURRENCYSTYLE);
        assertNotNull("NumberFormat is missing currency instance for STANDARDCURRENCYSTYLE", stdFmt.getCurrency());
        assertEquals("Currency instance is not for the desired locale for STANDARDCURRENCYSTYLE", cur, stdFmt.getCurrency());
        assertEquals("NumberFormat format outputs wrong value for STANDARDCURRENCYSTYLE", "-1.234,50 €", stdFmt.format(-1234.5d));
    }

    @Test
    public void TestCurrencyUsage() {
        // the 1st one is checking setter/getter, while the 2nd one checks for getInstance
        // compare the Currency and Currency Cash Digits
        // Note that as of CLDR 26:
        // * TWD and PKR switched from 0 decimals to 2; ISK still has 0, so change test to that
        // * CAD rounds to .05 in the cash style only.
        for (int i = 0; i < 2; i++) {
            String original_expected = "ISK 124";
            DecimalFormat custom = null;
            if (i == 0) {
                custom = (DecimalFormat) DecimalFormat.getInstance(new ULocale("en_US@currency=ISK"),
                        DecimalFormat.CURRENCYSTYLE);

                String original = custom.format(123.567);
                assertEquals("Test Currency Context", original_expected, original);

                // test the getter
                assertEquals("Test Currency Context Purpose", custom.getCurrencyUsage(),
                        Currency.CurrencyUsage.STANDARD);
                custom.setCurrencyUsage(Currency.CurrencyUsage.CASH);
                assertEquals("Test Currency Context Purpose", custom.getCurrencyUsage(), Currency.CurrencyUsage.CASH);
            } else {
                custom = (DecimalFormat) DecimalFormat.getInstance(new ULocale("en_US@currency=ISK"),
                        DecimalFormat.CASHCURRENCYSTYLE);

                // test the getter
                assertEquals("Test Currency Context Purpose", custom.getCurrencyUsage(), Currency.CurrencyUsage.CASH);
            }

            String cash_currency = custom.format(123.567);
            String cash_currency_expected = "ISK 124";
            assertEquals("Test Currency Context", cash_currency_expected, cash_currency);
        }

        // the 1st one is checking setter/getter, while the 2nd one checks for getInstance
        // compare the Currency and Currency Cash Rounding
        for (int i = 0; i < 2; i++) {
            String original_rounding_expected = "CA$123.57";
            DecimalFormat fmt = null;
            if (i == 0) {
                fmt = (DecimalFormat) DecimalFormat.getInstance(new ULocale("en_US@currency=CAD"),
                        DecimalFormat.CURRENCYSTYLE);

                String original_rounding = fmt.format(123.566);
                assertEquals("Test Currency Context", original_rounding_expected, original_rounding);

                fmt.setCurrencyUsage(Currency.CurrencyUsage.CASH);
            } else {
                fmt = (DecimalFormat) DecimalFormat.getInstance(new ULocale("en_US@currency=CAD"),
                        DecimalFormat.CASHCURRENCYSTYLE);
            }

            String cash_rounding_currency = fmt.format(123.567);
            String cash__rounding_currency_expected = "CA$123.55";
            assertEquals("Test Currency Context", cash__rounding_currency_expected, cash_rounding_currency);
        }

        // the 1st one is checking setter/getter, while the 2nd one checks for getInstance
        // Test the currency change
        for (int i = 0; i < 2; i++) {
            DecimalFormat fmt2 = null;
            if (i == 1) {
                fmt2 = (DecimalFormat) NumberFormat.getInstance(new ULocale("en_US@currency=JPY"),
                        NumberFormat.CURRENCYSTYLE);
                fmt2.setCurrencyUsage(Currency.CurrencyUsage.CASH);
            } else {
                fmt2 = (DecimalFormat) NumberFormat.getInstance(new ULocale("en_US@currency=JPY"),
                        NumberFormat.CASHCURRENCYSTYLE);
            }

            fmt2.setCurrency(Currency.getInstance("PKR"));
            String PKR_changed = fmt2.format(123.567);
            String PKR_changed_expected = "PKR 124";
            assertEquals("Test Currency Context", PKR_changed_expected, PKR_changed);
        }
    }

    @Test
    public void TestCurrencyWithMinMaxFractionDigits() {
        DecimalFormat df = new DecimalFormat();
        df.applyPattern("¤#,##0.00");
        df.setCurrency(Currency.getInstance("USD"));
        assertEquals("Basic currency format fails", "$1.23", df.format(1.234));
        df.setMaximumFractionDigits(4);
        assertEquals("Currency with max fraction == 4", "$1.234", df.format(1.234));
        df.setMinimumFractionDigits(4);
        assertEquals("Currency with min fraction == 4", "$1.2340", df.format(1.234));
    }

    @Test
    public void TestParseRequiredDecimalPoint() {

        String[] testPattern = { "00.####", "00.0", "00" };

        String value2Parse = "99";
        String value2ParseWithDecimal = "99.9";
        double parseValue  =  99;
        double parseValueWithDecimal = 99.9;
        DecimalFormat parser = new DecimalFormat();
        double result;
        boolean hasDecimalPoint;
        for (int i = 0; i < testPattern.length; i++) {
            parser.applyPattern(testPattern[i]);
            hasDecimalPoint = testPattern[i].contains(".");

            parser.setDecimalPatternMatchRequired(false);
            try {
                result = parser.parse(value2Parse).doubleValue();
                assertEquals("wrong parsed value", parseValue, result);
            } catch (ParseException e) {
                TestFmwk.errln("Parsing " + value2Parse + " should have succeeded with " + testPattern[i] +
                            " and isDecimalPointMatchRequired set to: " + parser.isDecimalPatternMatchRequired());
            }
            try {
                result = parser.parse(value2ParseWithDecimal).doubleValue();
                assertEquals("wrong parsed value", parseValueWithDecimal, result);
            } catch (ParseException e) {
                TestFmwk.errln("Parsing " + value2ParseWithDecimal + " should have succeeded with " + testPattern[i] +
                            " and isDecimalPointMatchRequired set to: " + parser.isDecimalPatternMatchRequired());
            }

            parser.setDecimalPatternMatchRequired(true);
            try {
                result = parser.parse(value2Parse).doubleValue();
                if(hasDecimalPoint){
                    TestFmwk.errln("Parsing " + value2Parse + " should NOT have succeeded with " + testPattern[i] +
                            " and isDecimalPointMatchRequired set to: " + parser.isDecimalPatternMatchRequired());
                }
            } catch (ParseException e) {
                    // OK, should fail
            }
            try {
                result = parser.parse(value2ParseWithDecimal).doubleValue();
                if(!hasDecimalPoint){
                    TestFmwk.errln("Parsing " + value2ParseWithDecimal + " should NOT have succeeded with " + testPattern[i] +
                            " and isDecimalPointMatchRequired set to: " + parser.isDecimalPatternMatchRequired() +
                            " (got: " + result + ")");
                }
            } catch (ParseException e) {
                    // OK, should fail
            }
        }
    }

    @Test
    public void TestCurrFmtNegSameAsPositive() {
        DecimalFormatSymbols decfmtsym = DecimalFormatSymbols.getInstance(Locale.US);
        decfmtsym.setMinusSign('\u200B'); // ZERO WIDTH SPACE, in ICU4J cannot set to empty string
        DecimalFormat decfmt = new DecimalFormat("\u00A4#,##0.00;-\u00A4#,##0.00", decfmtsym);
        String currFmtResult = decfmt.format(-100.0);
        if (!currFmtResult.equals("\u200B$100.00")) {
            errln("decfmt.toPattern results wrong, expected \u200B$100.00, got " + currFmtResult);
        }
    }

    @Test
    public void TestNumberFormatTestDataToString() {
        new DataDrivenNumberFormatTestData().toString();
    }

   // Testing for Issue 11805.
    @Test
    public void TestFormatToCharacterIteratorIssue11805 () {
        final double number = -350.76;
        DecimalFormat dfUS = (DecimalFormat) DecimalFormat.getCurrencyInstance(Locale.US);
        String strUS = dfUS.format(number);
        Set<AttributedCharacterIterator.Attribute> resultUS  = dfUS.formatToCharacterIterator(number).getAllAttributeKeys();
        assertEquals("Negative US Results: " + strUS, 5, resultUS.size());

        // For each test, add assert that all the fields are present and in the right spot.
        // TODO: Add tests for identify and position of each field, as in IntlTestDecimalFormatAPIC.

        DecimalFormat dfDE = (DecimalFormat) DecimalFormat.getCurrencyInstance(Locale.GERMANY);
        String strDE = dfDE.format(number);
        Set<AttributedCharacterIterator.Attribute> resultDE  = dfDE.formatToCharacterIterator(number).getAllAttributeKeys();
        assertEquals("Negative DE Results: " + strDE, 5, resultDE.size());

        DecimalFormat dfIN = (DecimalFormat) DecimalFormat.getCurrencyInstance(new Locale("hi", "in"));
        String strIN = dfIN.format(number);
        Set<AttributedCharacterIterator.Attribute> resultIN  = dfIN.formatToCharacterIterator(number).getAllAttributeKeys();
        assertEquals("Negative IN Results: " + strIN, 5, resultIN.size());

        DecimalFormat dfJP = (DecimalFormat) DecimalFormat.getCurrencyInstance(Locale.JAPAN);
        String strJP = dfJP.format(number);
        Set<AttributedCharacterIterator.Attribute> resultJP  = dfJP.formatToCharacterIterator(number).getAllAttributeKeys();
        assertEquals("Negative JA Results: " + strJP, 3, resultJP.size());

        DecimalFormat dfGB = (DecimalFormat) DecimalFormat.getCurrencyInstance(new Locale("en", "gb"));
        String strGB = dfGB.format(number);
        Set<AttributedCharacterIterator.Attribute> resultGB  = dfGB.formatToCharacterIterator(number).getAllAttributeKeys();
        assertEquals("Negative GB Results: " + strGB , 5, resultGB.size());

        DecimalFormat dfPlural = (DecimalFormat) NumberFormat.getInstance(new Locale("en", "gb"),
            NumberFormat.PLURALCURRENCYSTYLE);
        strGB = dfPlural.format(number);
        resultGB = dfPlural.formatToCharacterIterator(number).getAllAttributeKeys();
        assertEquals("Negative GB Results: " + strGB , 5, resultGB.size());

        strGB = dfPlural.format(1);
        resultGB = dfPlural.formatToCharacterIterator(1).getAllAttributeKeys();
        assertEquals("Negative GB Results: " + strGB , 4, resultGB.size());

        // Test output with unit value.
        DecimalFormat auPlural = (DecimalFormat) NumberFormat.getInstance(new Locale("en", "au"),
                NumberFormat.PLURALCURRENCYSTYLE);
        String strAU = auPlural.format(1L);
        Set<AttributedCharacterIterator.Attribute> resultAU  =
                auPlural.formatToCharacterIterator(1L).getAllAttributeKeys();
        assertEquals("Unit AU Result: " + strAU , 4, resultAU.size());

        // Verify Permille fields.
        DecimalFormatSymbols sym = new DecimalFormatSymbols(new Locale("en", "gb"));
        DecimalFormat dfPermille = new DecimalFormat("####0.##\u2030", sym);
        strGB = dfPermille.format(number);
        resultGB = dfPermille.formatToCharacterIterator(number).getAllAttributeKeys();
        assertEquals("Negative GB Permille Results: " + strGB , 3, resultGB.size());
    }

    // Testing for Issue 11808.
    @Test
    public void TestRoundUnnecessarytIssue11808 () {
        DecimalFormat df = (DecimalFormat) DecimalFormat.getInstance();
        StringBuffer result = new StringBuffer("");
        df.setRoundingMode(BigDecimal.ROUND_UNNECESSARY);
        df.applyPattern("00.0#E0");

        try {
            df.format(99999.0, result, new FieldPosition(0));
            fail("Missing ArithmeticException for double: " + result);
        } catch (ArithmeticException expected) {
            // The exception should be thrown, since rounding is needed.
        }

        try {
            result = df.format(99999, result, new FieldPosition(0));
            fail("Missing ArithmeticException for int: " + result);
       } catch (ArithmeticException expected) {
           // The exception should be thrown, since rounding is needed.
        }

        try {
            result = df.format(new BigInteger("999999"), result, new FieldPosition(0));
            fail("Missing ArithmeticException for BigInteger: " + result);
        } catch (ArithmeticException expected) {
            // The exception should be thrown, since rounding is needed.
        }

        try {
            result = df.format(new BigDecimal("99999"), result, new FieldPosition(0));
            fail("Missing ArithmeticException for BigDecimal: " + result);
        } catch (ArithmeticException expected) {
            // The exception should be thrown, since rounding is needed.
        }

        try {
            result = df.format(new BigDecimal("-99999"), result, new FieldPosition(0));
            fail("Missing ArithmeticException for BigDecimal: " + result);
        } catch (ArithmeticException expected) {
            // The exception should be thrown, since rounding is needed.
        }
    }

    // Testing for Issue 11735.
    @Test
    public void TestNPEIssue11735() {
        DecimalFormat fmt = new DecimalFormat("0", new DecimalFormatSymbols(new ULocale("en")));
        ParsePosition ppos = new ParsePosition(0);
        assertEquals("Currency symbol missing in parse. Expect null result.",
                fmt.parseCurrency("53.45", ppos), null);
    }

    private void CompareAttributedCharacterFormatOutput(AttributedCharacterIterator iterator,
        List<FieldContainer> expected, String formattedOutput) {

        List<FieldContainer> result = new ArrayList<>();
        while (iterator.getIndex() != iterator.getEndIndex()) {
            int start = iterator.getRunStart();
            int end = iterator.getRunLimit();
            Iterator it = iterator.getAttributes().keySet().iterator();
            AttributedCharacterIterator.Attribute attribute = (AttributedCharacterIterator.Attribute) it.next();
            // For positions with both INTEGER and GROUPING attributes, we want the GROUPING attribute.
            if (it.hasNext() && attribute.equals(NumberFormat.Field.INTEGER)) {
                attribute = (AttributedCharacterIterator.Attribute) it.next();
            }
            Object value = iterator.getAttribute(attribute);
            result.add(new FieldContainer(start, end, attribute, value));
            iterator.setIndex(end);
        }
        assertEquals("Comparing vector length for " + formattedOutput,
            expected.size(), result.size());

        if (!expected.containsAll(result)) {
          // Print information on the differences.
          for (int i = 0; i < expected.size(); i++) {
            System.out.println("     expected[" + i + "] =" +
                expected.get(i).start + " " +
                expected.get(i).end + " " +
                expected.get(i).attribute + " " +
                expected.get(i).value);
            System.out.println(" result[" + i + "] =" +
                result.get(i).start + " " +
                result.get(i).end + " " +
                result.get(i).attribute + " " +
                result.get(i).value);
          }
        }
        assertTrue("Comparing vector results for " + formattedOutput, expected.containsAll(result));
    }

    // Testing for Issue 11914, missing FieldPositions for some field types.
    @Test
    public void TestNPEIssue11914() {
        // First test: Double value with grouping separators.
        List<FieldContainer> v1 = new ArrayList<>(7);
        v1.add(new FieldContainer(0, 3, NumberFormat.Field.INTEGER));
        v1.add(new FieldContainer(3, 4, NumberFormat.Field.GROUPING_SEPARATOR));
        v1.add(new FieldContainer(4, 7, NumberFormat.Field.INTEGER));
        v1.add(new FieldContainer(7, 8, NumberFormat.Field.GROUPING_SEPARATOR));
        v1.add(new FieldContainer(8, 11, NumberFormat.Field.INTEGER));
        v1.add(new FieldContainer(11, 12, NumberFormat.Field.DECIMAL_SEPARATOR));
        v1.add(new FieldContainer(12, 15, NumberFormat.Field.FRACTION));

        Number number = new Double(123456789.9753);
        ULocale usLoc = new ULocale("en-US");
        DecimalFormatSymbols US = new DecimalFormatSymbols(usLoc);

        NumberFormat outFmt = NumberFormat.getNumberInstance(usLoc);
        String numFmtted = outFmt.format(number);
        AttributedCharacterIterator iterator =
                outFmt.formatToCharacterIterator(number);
        CompareAttributedCharacterFormatOutput(iterator, v1, numFmtted);

        // Second test: Double with scientific notation formatting.
        List<FieldContainer> v2 = new ArrayList<>(7);
        v2.add(new FieldContainer(0, 1, NumberFormat.Field.INTEGER));
        v2.add(new FieldContainer(1, 2, NumberFormat.Field.DECIMAL_SEPARATOR));
        v2.add(new FieldContainer(2, 5, NumberFormat.Field.FRACTION));
        v2.add(new FieldContainer(5, 6, NumberFormat.Field.EXPONENT_SYMBOL));
        v2.add(new FieldContainer(6, 7, NumberFormat.Field.EXPONENT_SIGN));
        v2.add(new FieldContainer(7, 8, NumberFormat.Field.EXPONENT));
        DecimalFormat fmt2 = new DecimalFormat("0.###E+0", US);

        numFmtted = fmt2.format(number);
        iterator = fmt2.formatToCharacterIterator(number);
        CompareAttributedCharacterFormatOutput(iterator, v2, numFmtted);

        // Third test. BigInteger with grouping separators.
        List<FieldContainer> v3 = new ArrayList<>(7);
        v3.add(new FieldContainer(0, 1, NumberFormat.Field.SIGN));
        v3.add(new FieldContainer(1, 2, NumberFormat.Field.INTEGER));
        v3.add(new FieldContainer(2, 3, NumberFormat.Field.GROUPING_SEPARATOR));
        v3.add(new FieldContainer(3, 6, NumberFormat.Field.INTEGER));
        v3.add(new FieldContainer(6, 7, NumberFormat.Field.GROUPING_SEPARATOR));
        v3.add(new FieldContainer(7, 10, NumberFormat.Field.INTEGER));
        v3.add(new FieldContainer(10, 11, NumberFormat.Field.GROUPING_SEPARATOR));
        v3.add(new FieldContainer(11, 14, NumberFormat.Field.INTEGER));
        v3.add(new FieldContainer(14, 15, NumberFormat.Field.GROUPING_SEPARATOR));
        v3.add(new FieldContainer(15, 18, NumberFormat.Field.INTEGER));
        v3.add(new FieldContainer(18, 19, NumberFormat.Field.GROUPING_SEPARATOR));
        v3.add(new FieldContainer(19, 22, NumberFormat.Field.INTEGER));
        v3.add(new FieldContainer(22, 23, NumberFormat.Field.GROUPING_SEPARATOR));
        v3.add(new FieldContainer(23, 26, NumberFormat.Field.INTEGER));
        BigInteger bigNumberInt = new BigInteger("-1234567890246813579");
        String fmtNumberBigInt = outFmt.format(bigNumberInt);

        iterator = outFmt.formatToCharacterIterator(bigNumberInt);
        CompareAttributedCharacterFormatOutput(iterator, v3, fmtNumberBigInt);

        // Fourth test: BigDecimal with exponential formatting.
        List<FieldContainer> v4 = new ArrayList<>(7);
        v4.add(new FieldContainer(0, 1, NumberFormat.Field.SIGN));
        v4.add(new FieldContainer(1, 2, NumberFormat.Field.INTEGER));
        v4.add(new FieldContainer(2, 3, NumberFormat.Field.DECIMAL_SEPARATOR));
        v4.add(new FieldContainer(3, 6, NumberFormat.Field.FRACTION));
        v4.add(new FieldContainer(6, 7, NumberFormat.Field.EXPONENT_SYMBOL));
        v4.add(new FieldContainer(7, 8, NumberFormat.Field.EXPONENT_SIGN));
        v4.add(new FieldContainer(8, 9, NumberFormat.Field.EXPONENT));

        java.math.BigDecimal numberBigD = new java.math.BigDecimal(-123456789);
        String fmtNumberBigDExp = fmt2.format(numberBigD);

        iterator = fmt2.formatToCharacterIterator(numberBigD);
        CompareAttributedCharacterFormatOutput(iterator, v4, fmtNumberBigDExp);

    }

    // Test that the decimal is shown even when there are no fractional digits
    @Test
    public void Test11621() throws Exception {
        String pat = "0.##E0";

        DecimalFormatSymbols icuSym = new DecimalFormatSymbols(Locale.US);
        DecimalFormat icuFmt = new DecimalFormat(pat, icuSym);
        icuFmt.setDecimalSeparatorAlwaysShown(true);
        String icu = ((NumberFormat)icuFmt).format(299792458);

        java.text.DecimalFormatSymbols jdkSym = new java.text.DecimalFormatSymbols(Locale.US);
        java.text.DecimalFormat jdkFmt = new java.text.DecimalFormat(pat,jdkSym);
        jdkFmt.setDecimalSeparatorAlwaysShown(true);
        String jdk = ((java.text.NumberFormat)jdkFmt).format(299792458);

        assertEquals("ICU and JDK placement of decimal in exponent", jdk, icu);
    }

    private void checkFormatWithField(String testInfo, Format format, Object object,
            String expected, Format.Field field, int begin, int end) {
        StringBuffer buffer = new StringBuffer();
        FieldPosition pos = new FieldPosition(field);
        format.format(object, buffer, pos);

        assertEquals("Test " + testInfo + ": incorrect formatted text", expected, buffer.toString());

        if (begin != pos.getBeginIndex() || end != pos.getEndIndex()) {
            assertEquals("Index mismatch", field + " " + begin + ".." + end,
                pos.getFieldAttribute() + " " + pos.getBeginIndex() + ".." + pos.getEndIndex());
        }
    }

    @Test
    public void TestMissingFieldPositionsCurrency() {
        DecimalFormat formatter = (DecimalFormat) NumberFormat.getCurrencyInstance(ULocale.US);
        Number number = new Double(92314587.66);
        String result = "$92,314,587.66";

        checkFormatWithField("currency", formatter, number, result,
            NumberFormat.Field.CURRENCY, 0, 1);
        checkFormatWithField("integer", formatter, number, result,
            NumberFormat.Field.INTEGER, 1, 11);
        checkFormatWithField("grouping separator", formatter, number, result,
            NumberFormat.Field.GROUPING_SEPARATOR, 3, 4);
        checkFormatWithField("decimal separator", formatter, number, result,
            NumberFormat.Field.DECIMAL_SEPARATOR, 11, 12);
        checkFormatWithField("fraction", formatter, number, result,
            NumberFormat.Field.FRACTION, 12, 14);
    }

    @Test
    public void TestMissingFieldPositionsNegativeDouble() {
        // test for exponential fields with double
        DecimalFormatSymbols us_symbols = new DecimalFormatSymbols(ULocale.US);
        Number number = new Double(-12345678.90123);
        DecimalFormat formatter = new DecimalFormat("0.#####E+00", us_symbols);
        String numFmtted = formatter.format(number);

        checkFormatWithField("sign", formatter, number, numFmtted,
            NumberFormat.Field.SIGN, 0, 1);
        checkFormatWithField("integer", formatter, number, numFmtted,
            NumberFormat.Field.INTEGER, 1, 2);
        checkFormatWithField("decimal separator", formatter, number, numFmtted,
            NumberFormat.Field.DECIMAL_SEPARATOR, 2, 3);
        checkFormatWithField("exponent symbol", formatter, number, numFmtted,
            NumberFormat.Field.EXPONENT_SYMBOL, 8, 9);
        checkFormatWithField("exponent sign", formatter, number, numFmtted,
            NumberFormat.Field.EXPONENT_SIGN, 9, 10);
        checkFormatWithField("exponent", formatter, number, numFmtted,
            NumberFormat.Field.EXPONENT, 10, 12);
    }

    @Test
    public void TestMissingFieldPositionsPerCent() {
        // Check PERCENT
        DecimalFormat percentFormat = (DecimalFormat) NumberFormat.getPercentInstance(ULocale.US);
        Number number = new Double(-0.986);
        String numberFormatted = percentFormat.format(number);
        checkFormatWithField("sign", percentFormat, number, numberFormatted,
            NumberFormat.Field.SIGN, 0, 1);
        checkFormatWithField("integer", percentFormat, number, numberFormatted,
            NumberFormat.Field.INTEGER, 1, 3);
        checkFormatWithField("percent", percentFormat, number, numberFormatted,
            NumberFormat.Field.PERCENT, 3, 4);
    }

    @Test
    public void TestMissingFieldPositionsPerCentPattern() {
        // Check PERCENT with more digits
        DecimalFormatSymbols us_symbols = new DecimalFormatSymbols(ULocale.US);
        DecimalFormat fmtPercent = new DecimalFormat("0.#####%", us_symbols);
        Number number = new Double(-0.986);
        String numFmtted = fmtPercent.format(number);

        checkFormatWithField("sign", fmtPercent, number, numFmtted,
            NumberFormat.Field.SIGN, 0, 1);
        checkFormatWithField("integer", fmtPercent, number, numFmtted,
            NumberFormat.Field.INTEGER, 1, 3);
        checkFormatWithField("decimal separator", fmtPercent, number, numFmtted,
            NumberFormat.Field.DECIMAL_SEPARATOR, 3, 4);
        checkFormatWithField("fraction", fmtPercent, number, numFmtted,
            NumberFormat.Field.FRACTION, 4, 5);
        checkFormatWithField("percent", fmtPercent, number, numFmtted,
            NumberFormat.Field.PERCENT, 5, 6);
    }

    @Test
    public void TestMissingFieldPositionsPerMille() {
        // Check PERMILLE
        DecimalFormatSymbols us_symbols = new DecimalFormatSymbols(ULocale.US);
        DecimalFormat fmtPerMille = new DecimalFormat("0.######‰", us_symbols);
        Number numberPermille = new Double(-0.98654);
        String numFmtted = fmtPerMille.format(numberPermille);

        checkFormatWithField("sign", fmtPerMille, numberPermille, numFmtted,
            NumberFormat.Field.SIGN, 0, 1);
        checkFormatWithField("integer", fmtPerMille, numberPermille, numFmtted,
            NumberFormat.Field.INTEGER, 1, 4);
        checkFormatWithField("decimal separator", fmtPerMille, numberPermille, numFmtted,
            NumberFormat.Field.DECIMAL_SEPARATOR, 4, 5);
        checkFormatWithField("fraction", fmtPerMille, numberPermille, numFmtted,
            NumberFormat.Field.FRACTION, 5, 7);
        checkFormatWithField("permille", fmtPerMille, numberPermille, numFmtted,
            NumberFormat.Field.PERMILLE, 7, 8);
    }

    @Test
    public void TestMissingFieldPositionsNegativeBigInt() {
      DecimalFormatSymbols us_symbols = new DecimalFormatSymbols(ULocale.US);
        DecimalFormat formatter = new DecimalFormat("0.#####E+0", us_symbols);
        Number number = new BigDecimal("-123456789987654321");
        String bigDecFmtted = formatter.format(number);

        checkFormatWithField("sign", formatter, number, bigDecFmtted,
            NumberFormat.Field.SIGN, 0, 1);
        checkFormatWithField("integer", formatter, number, bigDecFmtted,
            NumberFormat.Field.INTEGER, 1, 2);
        checkFormatWithField("decimal separator", formatter, number, bigDecFmtted,
            NumberFormat.Field.DECIMAL_SEPARATOR, 2, 3);
        checkFormatWithField("exponent symbol", formatter, number, bigDecFmtted,
            NumberFormat.Field.EXPONENT_SYMBOL, 8, 9);
        checkFormatWithField("exponent sign", formatter, number, bigDecFmtted,
            NumberFormat.Field.EXPONENT_SIGN, 9, 10);
        checkFormatWithField("exponent", formatter, number, bigDecFmtted,
            NumberFormat.Field.EXPONENT, 10, 12);
    }

    @Test
    public void TestMissingFieldPositionsNegativeLong() {
        Number number = new Long("-123456789987654321");
        DecimalFormatSymbols us_symbols = new DecimalFormatSymbols(ULocale.US);
        DecimalFormat formatter = new DecimalFormat("0.#####E+0", us_symbols);
        String longFmtted = formatter.format(number);

        checkFormatWithField("sign", formatter, number, longFmtted,
            NumberFormat.Field.SIGN, 0, 1);
        checkFormatWithField("integer", formatter, number, longFmtted,
            NumberFormat.Field.INTEGER, 1, 2);
        checkFormatWithField("decimal separator", formatter, number, longFmtted,
            NumberFormat.Field.DECIMAL_SEPARATOR, 2, 3);
        checkFormatWithField("exponent symbol", formatter, number, longFmtted,
            NumberFormat.Field.EXPONENT_SYMBOL, 8, 9);
        checkFormatWithField("exponent sign", formatter, number, longFmtted,
            NumberFormat.Field.EXPONENT_SIGN, 9, 10);
        checkFormatWithField("exponent", formatter, number, longFmtted,
            NumberFormat.Field.EXPONENT, 10, 12);
    }

    @Test
    public void TestMissingFieldPositionsPositiveBigDec() {
        // Check complex positive;negative pattern.
        DecimalFormatSymbols us_symbols = new DecimalFormatSymbols(ULocale.US);
        DecimalFormat fmtPosNegSign = new DecimalFormat("+0.####E+00;-0.#######E+0", us_symbols);
        Number positiveExp = new Double("9876543210");
        String posExpFormatted = fmtPosNegSign.format(positiveExp);

        checkFormatWithField("sign", fmtPosNegSign, positiveExp, posExpFormatted,
            NumberFormat.Field.SIGN, 0, 1);
        checkFormatWithField("integer", fmtPosNegSign, positiveExp, posExpFormatted,
            NumberFormat.Field.INTEGER, 1, 2);
        checkFormatWithField("decimal separator", fmtPosNegSign, positiveExp, posExpFormatted,
            NumberFormat.Field.DECIMAL_SEPARATOR, 2, 3);
        checkFormatWithField("fraction", fmtPosNegSign, positiveExp, posExpFormatted,
            NumberFormat.Field.FRACTION, 3, 7);
        checkFormatWithField("exponent symbol", fmtPosNegSign, positiveExp, posExpFormatted,
            NumberFormat.Field.EXPONENT_SYMBOL, 7, 8);
        checkFormatWithField("exponent sign", fmtPosNegSign, positiveExp, posExpFormatted,
            NumberFormat.Field.EXPONENT_SIGN, 8, 9);
        checkFormatWithField("exponent", fmtPosNegSign, positiveExp, posExpFormatted,
            NumberFormat.Field.EXPONENT, 9, 11);
    }

    @Test
    public void TestMissingFieldPositionsNegativeBigDec() {
        // Check complex positive;negative pattern.
      DecimalFormatSymbols us_symbols = new DecimalFormatSymbols(ULocale.US);
        DecimalFormat fmtPosNegSign = new DecimalFormat("+0.####E+00;-0.#######E+0", us_symbols);
        Number negativeExp = new BigDecimal("-0.000000987654321083");
        String negExpFormatted = fmtPosNegSign.format(negativeExp);

        checkFormatWithField("sign", fmtPosNegSign, negativeExp, negExpFormatted,
            NumberFormat.Field.SIGN, 0, 1);
        checkFormatWithField("integer", fmtPosNegSign, negativeExp, negExpFormatted,
            NumberFormat.Field.INTEGER, 1, 2);
        checkFormatWithField("decimal separator", fmtPosNegSign, negativeExp, negExpFormatted,
            NumberFormat.Field.DECIMAL_SEPARATOR, 2, 3);
        checkFormatWithField("fraction", fmtPosNegSign, negativeExp, negExpFormatted,
            NumberFormat.Field.FRACTION, 3, 7);
        checkFormatWithField("exponent symbol", fmtPosNegSign, negativeExp, negExpFormatted,
            NumberFormat.Field.EXPONENT_SYMBOL, 7, 8);
        checkFormatWithField("exponent sign", fmtPosNegSign, negativeExp, negExpFormatted,
            NumberFormat.Field.EXPONENT_SIGN, 8, 9);
        checkFormatWithField("exponent", fmtPosNegSign, negativeExp, negExpFormatted,
            NumberFormat.Field.EXPONENT, 9, 11);
    }

    @Test
    public void TestStringSymbols() {
        DecimalFormatSymbols symbols = new DecimalFormatSymbols(ULocale.US);

        // Attempt digits with multiple code points.
        String[] customDigits = {"(0)", "(1)", "(2)", "(3)", "(4)", "(5)", "(6)", "(7)", "(8)", "(9)"};
        symbols.setDigitStrings(customDigits);
        DecimalFormat fmt = new DecimalFormat("#,##0.0#", symbols);
        expect2(fmt, 1234567.89, "(1),(2)(3)(4),(5)(6)(7).(8)(9)");

        // Scientific notation should work.
        fmt.applyPattern("@@@E0");
        expect2(fmt, 1230000, "(1).(2)(3)E(6)");

        // Grouping and decimal with multiple code points (supported in parsing since ICU 61)
        symbols.setDecimalSeparatorString("~~");
        symbols.setGroupingSeparatorString("^^");
        fmt.setDecimalFormatSymbols(symbols);
        fmt.applyPattern("#,##0.0#");
        expect2(fmt, 1234567.89, "(1)^^(2)(3)(4)^^(5)(6)(7)~~(8)(9)");

        // Digits starting at U+1D7CE MATHEMATICAL BOLD DIGIT ZERO
        // These are all single code points, so parsing will work.
        for (int i=0; i<10; i++) customDigits[i] = new String(Character.toChars(0x1D7CE+i));
        symbols.setDigitStrings(customDigits);
        symbols.setDecimalSeparatorString("😁");
        symbols.setGroupingSeparatorString("😎");
        fmt.setDecimalFormatSymbols(symbols);
        expect2(fmt, 1234.56, "𝟏😎𝟐𝟑𝟒😁𝟓𝟔");
    }

    @Test
    public void TestArabicCurrencyPatternInfo() {
        ULocale arLocale = new ULocale("ar");

        DecimalFormatSymbols symbols = new DecimalFormatSymbols(arLocale);
        String currSpacingPatn = symbols.getPatternForCurrencySpacing(DecimalFormatSymbols.CURRENCY_SPC_CURRENCY_MATCH, true);
        if (currSpacingPatn==null || currSpacingPatn.length() == 0) {
            errln("locale ar, getPatternForCurrencySpacing returns null or 0-length string");
        }

        DecimalFormat currAcctFormat = (DecimalFormat)NumberFormat.getInstance(arLocale, NumberFormat.ACCOUNTINGCURRENCYSTYLE);
        String currAcctPatn = currAcctFormat.toPattern();
        if (currAcctPatn==null || currAcctPatn.length() == 0) {
            errln("locale ar, toPattern for ACCOUNTINGCURRENCYSTYLE returns null or 0-length string");
        }
    }

    @Test
    public void TestMinMaxOverrides()
            throws IllegalAccessException, IllegalArgumentException, InvocationTargetException,
                NoSuchMethodException, SecurityException {
        Class<?>[] baseClasses = {NumberFormat.class, NumberFormat.class, DecimalFormat.class};
        String[] names = {"Integer", "Fraction", "Significant"};
        for (int i = 0; i < 3; i++) {
            DecimalFormat df = new DecimalFormat();
            Class<?> base = baseClasses[i];
            String name = names[i];
            Method getMinimum = base.getDeclaredMethod("getMinimum" + name + "Digits");
            Method setMinimum = base.getDeclaredMethod("setMinimum" + name + "Digits", Integer.TYPE);
            Method getMaximum = base.getDeclaredMethod("getMaximum" + name + "Digits");
            Method setMaximum = base.getDeclaredMethod("setMaximum" + name + "Digits", Integer.TYPE);

            // Check max overrides min
            setMinimum.invoke(df, 2);
            assertEquals(name + " getMin A", 2, getMinimum.invoke(df));
            setMaximum.invoke(df, 3);
            assertEquals(name + " getMin B", 2, getMinimum.invoke(df));
            assertEquals(name + " getMax B", 3, getMaximum.invoke(df));
            setMaximum.invoke(df, 2);
            assertEquals(name + " getMin C", 2, getMinimum.invoke(df));
            assertEquals(name + " getMax C", 2, getMaximum.invoke(df));
            setMaximum.invoke(df, 1);
            assertEquals(name + " getMin D", 1, getMinimum.invoke(df));
            assertEquals(name + " getMax D", 1, getMaximum.invoke(df));

            // Check min overrides max
            setMaximum.invoke(df, 2);
            assertEquals(name + " getMax E", 2, getMaximum.invoke(df));
            setMinimum.invoke(df, 1);
            assertEquals(name + " getMin F", 1, getMinimum.invoke(df));
            assertEquals(name + " getMax F", 2, getMaximum.invoke(df));
            setMinimum.invoke(df, 2);
            assertEquals(name + " getMin G", 2, getMinimum.invoke(df));
            assertEquals(name + " getMax G", 2, getMaximum.invoke(df));
            setMinimum.invoke(df, 3);
            assertEquals(name + " getMin H", 3, getMinimum.invoke(df));
            assertEquals(name + " getMax H", 3, getMaximum.invoke(df));
        }
    }

    @Test
    public void TestSetMathContext() throws ParseException {
        java.math.MathContext fourDigits = new java.math.MathContext(4);
        java.math.MathContext unlimitedCeiling = new java.math.MathContext(0, RoundingMode.CEILING);

        // Test rounding
        DecimalFormat df = new DecimalFormat();
        assertEquals("Default format", "9,876.543", df.format(9876.5432));
        df.setMathContext(fourDigits);
        assertEquals("Format with fourDigits", "9,877", df.format(9876.5432));
        df.setMathContext(unlimitedCeiling);
        assertEquals("Format with unlimitedCeiling", "9,876.544", df.format(9876.5432));

        // Test multiplication
        df = new DecimalFormat("0.000%");
        assertEquals("Default multiplication", "12.001%", df.format(0.120011));
        df.setMathContext(fourDigits);
        assertEquals("Multiplication with fourDigits", "12.000%", df.format(0.120011));
        df.setMathContext(unlimitedCeiling);
        assertEquals("Multiplication with unlimitedCeiling", "12.002%", df.format(0.120011));

        // Test simple division
        df = new DecimalFormat("0%");
        assertEquals("Default division", 0.12001, df.parse("12.001%").doubleValue());
        df.setMathContext(fourDigits);
        // NOTE: Since ICU 61, division no longer occurs with percentage parsing.
        // assertEquals("Division with fourDigits", 0.12, df.parse("12.001%").doubleValue());
        assertEquals("Division with fourDigits", 0.12001, df.parse("12.001%").doubleValue());
        df.setMathContext(unlimitedCeiling);
        assertEquals("Division with unlimitedCeiling", 0.12001, df.parse("12.001%").doubleValue());

        // Test extreme division
        df = new DecimalFormat();
        df.setMultiplier(1000000007); // prime number
        String hugeNumberString = "9876543212345678987654321234567898765432123456789"; // 49 digits
        BigInteger huge34Digits = new BigInteger("9876543143209876985185182338271622000000");
        BigInteger huge4Digits = new BigInteger("9877000000000000000000000000000000000000");
        BigInteger actual34Digits = ((BigDecimal) df.parse(hugeNumberString)).toBigIntegerExact();
        assertEquals("Default extreme division", huge34Digits, actual34Digits);
        df.setMathContext(fourDigits);
        BigInteger actual4Digits = ((BigDecimal) df.parse(hugeNumberString)).toBigIntegerExact();
        assertEquals("Extreme division with fourDigits", huge4Digits, actual4Digits);
    }

    /**
     * ArithmeticException is thrown when inverting multiplier produces a non-terminating
     * decimal result in conjunction with MathContext of unlimited precision.
     */
    @Test
    public void testSetMathContextArithmeticException() {
        DecimalFormat df = new DecimalFormat();
        df.setMultiplier(7);
        try {
            df.setMathContext(java.math.MathContext.UNLIMITED);
            fail("Extreme division with unlimited precision should throw ArithmeticException");
        } catch (ArithmeticException e) {
            // expected
        }
    }

    /**
     * ArithmeticException is thrown when inverting multiplier produces a non-terminating
     * decimal result in conjunction with MathContext of unlimited precision.
     */
    @Test
    public void testSetMathContextICUArithmeticException() {
        DecimalFormat df = new DecimalFormat();
        df.setMultiplier(7);
        try {
            df.setMathContextICU(new MathContext(0));
            fail("Extreme division with unlimited precision should throw ArithmeticException");
        } catch (ArithmeticException e) {
            // expected
        }
    }

    /**
     * ArithmeticException is thrown when inverting multiplier produces a non-terminating
     * decimal result in conjunction with MathContext of unlimited precision.
     */
    @Test
    public void testSetMultiplierArithmeticException() {
        DecimalFormat df = new DecimalFormat();
        df.setMathContext(java.math.MathContext.UNLIMITED);
        try {
            df.setMultiplier(7);
            fail("Extreme division with unlimited precision should throw ArithmeticException");
        } catch (ArithmeticException e) {
            // expected
        }
    }

    @Test
    public void Test10436() {
        DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(Locale.ENGLISH);
        df.setRoundingMode(MathContext.ROUND_CEILING);
        df.setMinimumFractionDigits(0);
        df.setMaximumFractionDigits(0);
        assertEquals("-.99 should round toward infinity", "-0", df.format(-0.99));
    }

    @Test
    public void Test10765() {
        NumberFormat fmt = NumberFormat.getInstance(new ULocale("en"));
        fmt.setMinimumIntegerDigits(10);
        FieldPosition pos = new FieldPosition(NumberFormat.Field.GROUPING_SEPARATOR);
        StringBuffer sb = new StringBuffer();
        fmt.format(1234567, sb, pos);
        assertEquals("Should have multiple grouping separators", "0,001,234,567", sb.toString());
        assertEquals("FieldPosition should report the first occurence", 1, pos.getBeginIndex());
        assertEquals("FieldPosition should report the first occurence", 2, pos.getEndIndex());
    }

    @Test
    public void Test10997() {
        NumberFormat fmt = NumberFormat.getCurrencyInstance(new ULocale("en-US"));
        fmt.setMinimumFractionDigits(4);
        fmt.setMaximumFractionDigits(4);
        String str1 = fmt.format(new CurrencyAmount(123.45, Currency.getInstance("USD")));
        String str2 = fmt.format(new CurrencyAmount(123.45, Currency.getInstance("EUR")));
        assertEquals("minFrac 4 should be respected in default currency", "$123.4500", str1);
        assertEquals("minFrac 4 should be respected in different currency", "€123.4500", str2);
    }

    @Test
    public void Test11020() {
        DecimalFormatSymbols sym = new DecimalFormatSymbols(ULocale.FRANCE);
        DecimalFormat fmt = new DecimalFormat("0.05E0", sym);
        String result = fmt.format(12301.2).replace('\u00a0', ' ');
        assertEquals("Rounding increment should be applied after magnitude scaling", "1,25E4", result);
    }

    @Test
    public void Test11025() {
        String pattern = "¤¤ **####0.00";
        DecimalFormatSymbols sym = new DecimalFormatSymbols(ULocale.FRANCE);
        DecimalFormat fmt = new DecimalFormat(pattern, sym);
        String result = fmt.format(433.0);
        assertEquals("Number should be padded to 11 characters", "EUR *433,00", result);
    }

    @Test
    public void Test11640_TripleCurrencySymbol() {
        DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();
        df.applyPattern("¤¤¤ 0");
        String result = df.getPositivePrefix();
        assertEquals("Triple-currency should give long name on getPositivePrefix", "US dollars ", result);
    }

    @Test
    public void Test11645() {
        String pattern = "#,##0.0#";
        DecimalFormat fmt = (DecimalFormat) NumberFormat.getInstance();
        fmt.applyPattern(pattern);
        DecimalFormat fmtCopy;

        final int newMultiplier = 37;
        fmtCopy = (DecimalFormat) fmt.clone();
        assertNotEquals("Value before setter", fmtCopy.getMultiplier(), newMultiplier);
        fmtCopy.setMultiplier(newMultiplier);
        assertEquals("Value after setter", fmtCopy.getMultiplier(), newMultiplier);
        fmtCopy.applyPattern(pattern);
        assertEquals("Value after applyPattern", fmtCopy.getMultiplier(), newMultiplier);
        assertFalse("multiplier", fmt.equals(fmtCopy));

        final int newRoundingMode = RoundingMode.CEILING.ordinal();
        fmtCopy = (DecimalFormat) fmt.clone();
        assertNotEquals("Value before setter", fmtCopy.getRoundingMode(), newRoundingMode);
        fmtCopy.setRoundingMode(newRoundingMode);
        assertEquals("Value after setter", fmtCopy.getRoundingMode(), newRoundingMode);
        fmtCopy.applyPattern(pattern);
        assertEquals("Value after applyPattern", fmtCopy.getRoundingMode(), newRoundingMode);
        assertFalse("roundingMode", fmt.equals(fmtCopy));

        final Currency newCurrency = Currency.getInstance("EAT");
        fmtCopy = (DecimalFormat) fmt.clone();
        assertNotEquals("Value before setter", fmtCopy.getCurrency(), newCurrency);
        fmtCopy.setCurrency(newCurrency);
        assertEquals("Value after setter", fmtCopy.getCurrency(), newCurrency);
        fmtCopy.applyPattern(pattern);
        assertEquals("Value after applyPattern", fmtCopy.getCurrency(), newCurrency);
        assertFalse("currency", fmt.equals(fmtCopy));

        final CurrencyUsage newCurrencyUsage = CurrencyUsage.CASH;
        fmtCopy = (DecimalFormat) fmt.clone();
        assertNotEquals("Value before setter", fmtCopy.getCurrencyUsage(), newCurrencyUsage);
        fmtCopy.setCurrencyUsage(CurrencyUsage.CASH);
        assertEquals("Value after setter", fmtCopy.getCurrencyUsage(), newCurrencyUsage);
        fmtCopy.applyPattern(pattern);
        assertEquals("Value after applyPattern", fmtCopy.getCurrencyUsage(), newCurrencyUsage);
        assertFalse("currencyUsage", fmt.equals(fmtCopy));
    }

    @Test
    public void Test11646() {
        DecimalFormatSymbols symbols = new DecimalFormatSymbols(new ULocale("en_US"));
        String pattern = "\u00a4\u00a4\u00a4 0.00 %\u00a4\u00a4";
        DecimalFormat fmt = new DecimalFormat(pattern, symbols);

        // Test equality with affixes. set affix methods can't capture special
        // characters which is why equality should fail.
        {
          DecimalFormat fmtCopy = (DecimalFormat) fmt.clone();
          assertEquals("", fmt, fmtCopy);
          fmtCopy.setPositivePrefix(fmtCopy.getPositivePrefix());
          assertNotEquals("", fmt, fmtCopy);
        }
        {
          DecimalFormat fmtCopy = (DecimalFormat) fmt.clone();
          assertEquals("", fmt, fmtCopy);
          fmtCopy.setPositiveSuffix(fmtCopy.getPositiveSuffix());
          assertNotEquals("", fmt, fmtCopy);
        }
        {
          DecimalFormat fmtCopy = (DecimalFormat) fmt.clone();
          assertEquals("", fmt, fmtCopy);
          fmtCopy.setNegativePrefix(fmtCopy.getNegativePrefix());
          assertNotEquals("", fmt, fmtCopy);
        }
        {
          DecimalFormat fmtCopy = (DecimalFormat) fmt.clone();
          assertEquals("", fmt, fmtCopy);
          fmtCopy.setNegativeSuffix(fmtCopy.getNegativeSuffix());
          assertNotEquals("", fmt, fmtCopy);
        }
    }

    @Test
    public void Test11648() {
        DecimalFormat df = new DecimalFormat("0.00");
        df.setScientificNotation(true);
        String pat = df.toPattern();
        assertEquals("A valid scientific notation pattern should be produced", "0.00E0", pat);
    }

    @Test
    public void Test11649() {
        String pattern = "\u00a4\u00a4\u00a4 0.00";
        DecimalFormat fmt = new DecimalFormat(pattern);
        fmt.setCurrency(Currency.getInstance("USD"));
        assertEquals("Triple currency sign should format long name", "US dollars 12.34", fmt.format(12.34));

        String newPattern = fmt.toPattern();
        assertEquals("Should produce a valid pattern", pattern, newPattern);

        DecimalFormat fmt2 = new DecimalFormat(newPattern);
        fmt2.setCurrency(Currency.getInstance("USD"));
        assertEquals("Triple currency sign pattern should round-trip", "US dollars 12.34", fmt2.format(12.34));

        String quotedPattern = "\u00a4\u00a4'\u00a4' 0.00";
        DecimalFormat fmt3 = new DecimalFormat(quotedPattern);
        assertEquals("Should be treated as double currency sign", "USD\u00a4 12.34", fmt3.format(12.34));

        String outQuotedPattern = fmt3.toPattern();
        assertEquals("Double currency sign with quoted sign should round-trip", quotedPattern, outQuotedPattern);
    }

    @Test
    @Ignore
    public void Test11686() {
        // Only passes with slow mode.
        // TODO: Re-enable this test with slow mode.
        DecimalFormat df = new DecimalFormat();
        df.setPositiveSuffix("0K");
        df.setNegativeSuffix("0N");
        expect2(df, 123, "1230K");
        expect2(df, -123, "-1230N");
    }

    @Test
    public void Test11839() {
        DecimalFormatSymbols dfs = new DecimalFormatSymbols(ULocale.ENGLISH);
        dfs.setMinusSignString("a∸");
        dfs.setPlusSignString("b∔"); //  ∔  U+2214 DOT PLUS
        DecimalFormat df = new DecimalFormat("0.00+;0.00-", dfs);
        String result = df.format(-1.234);
        assertEquals("Locale-specific minus sign should be used", "1.23a∸", result);
        result = df.format(1.234);
        assertEquals("Locale-specific plus sign should be used", "1.23b∔", result);
        // Test round-trip with parse
        expect2(df, -456, "456.00a∸");
        expect2(df, 456, "456.00b∔");
    }

    @Test
    public void Test12753() {
        ULocale locale = new ULocale("en-US");
        DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(locale);
        symbols.setDecimalSeparator('*');
        DecimalFormat df = new DecimalFormat("0.00", symbols);
        df.setDecimalPatternMatchRequired(true);
        try {
            df.parse("123");
            fail("Parsing integer succeeded even though setDecimalPatternMatchRequired was set");
        } catch (ParseException e) {
            // Parse failed (expected)
        }
    }

    @Test
    public void Test12962() {
        String pat = "**0.00";
        DecimalFormat df = new DecimalFormat(pat);
        String newPat = df.toPattern();
        assertEquals("Format width changed upon calling applyPattern", pat.length(), newPat.length());
    }

    @Test
    public void Test10354() {
        DecimalFormatSymbols dfs = new DecimalFormatSymbols();
        dfs.setNaN("");
        DecimalFormat df = new DecimalFormat();
        df.setDecimalFormatSymbols(dfs);
        try {
            df.formatToCharacterIterator(Double.NaN);
            // pass
        } catch (IllegalArgumentException e) {
            throw new AssertionError(e);
        }
    }

    @Test
    public void Test11913() {
        NumberFormat df = DecimalFormat.getInstance();
        String result = df.format(new BigDecimal("1.23456789E400"));
        assertEquals("Should format more than 309 digits", "12,345,678", result.substring(0, 10));
        assertEquals("Should format more than 309 digits", 534, result.length());
    }

    @Test
    public void Test12045() {
        if (logKnownIssue("12045", "XSU is missing from fr")) { return; }

        NumberFormat nf = NumberFormat.getInstance(new ULocale("fr"), NumberFormat.PLURALCURRENCYSTYLE);
        ParsePosition ppos = new ParsePosition(0);
        try {
            CurrencyAmount result = nf.parseCurrency("2,34 XSU", ppos);
            assertEquals("Parsing should succeed on XSU",
                         new CurrencyAmount(2.34, Currency.getInstance("XSU")), result);
            // pass
        } catch (Exception e) {
            //throw new AssertionError("Should have been able to parse XSU", e);
            throw new AssertionError("Should have been able to parse XSU: " + e.getMessage());
        }
    }

    @Test
    public void Test11739() {
        NumberFormat nf = NumberFormat.getCurrencyInstance(new ULocale("sr_BA"));
        ((DecimalFormat) nf).applyPattern("#,##0.0 ¤¤¤");
        ParsePosition ppos = new ParsePosition(0);
        CurrencyAmount result = nf.parseCurrency("1.500 амерички долар", ppos);
        assertEquals("Should parse to 1500 USD", new CurrencyAmount(1500, Currency.getInstance("USD")), result);
    }

    @Test
    public void Test11647() {
        DecimalFormat df = new DecimalFormat();
        df.applyPattern("¤¤¤¤#");
        String actual = df.format(123);
        assertEquals("Should replace 4 currency signs with U+FFFD", "\uFFFD123", actual);
    }

    @Test
    public void Test12567() {
        DecimalFormat df1 = (DecimalFormat) NumberFormat.getInstance(NumberFormat.PLURALCURRENCYSTYLE);
        DecimalFormat df2 = (DecimalFormat) NumberFormat.getInstance(NumberFormat.NUMBERSTYLE);
        df2.setCurrency(df1.getCurrency());
        df2.setCurrencyPluralInfo(df1.getCurrencyPluralInfo());
        df1.applyPattern("0.00");
        df2.applyPattern("0.00");
        assertEquals("df1 == df2", df1, df2);
        assertEquals("df2 == df1", df2, df1);
        df2.setPositivePrefix("abc");
        assertNotEquals("df1 != df2", df1, df2);
        assertNotEquals("df2 != df1", df2, df1);
    }

    @Test
    public void Test11897_LocalizedPatternSeparator() {
        // In a locale with a different <list> symbol, like arabic,
        // kPatternSeparatorSymbol should still be ';'
        {
            DecimalFormatSymbols dfs = new DecimalFormatSymbols(new ULocale("ar"));
            assertEquals("pattern separator symbol should be ;",
                    ';',
                    dfs.getPatternSeparator());
        }

        // However, the custom symbol should be used in localized notation
        // when set manually via API
        {
            DecimalFormatSymbols dfs = new DecimalFormatSymbols(new ULocale("en"));
            dfs.setPatternSeparator('!');
            DecimalFormat df = new DecimalFormat("0", dfs);
            df.applyPattern("a0;b0"); // should not throw
            assertEquals("should apply the normal pattern",
                    df.getNegativePrefix(),
                    "b");
            df.applyLocalizedPattern("c0!d0"); // should not throw
            assertEquals("should apply the localized pattern",
                    df.getNegativePrefix(),
                    "d");
        }
    }

    @Test
    public void Test13055() {
        DecimalFormat df = (DecimalFormat) NumberFormat.getPercentInstance();
        df.setMaximumFractionDigits(0);
        df.setRoundingMode(BigDecimal.ROUND_HALF_EVEN);
        assertEquals("Should round percent toward even number", "216%", df.format(2.155));
    }

    @Test
    public void Test13056() {
        DecimalFormat df = new DecimalFormat("#,##0");
        assertEquals("Primary grouping should return 3", 3, df.getGroupingSize());
        assertEquals("Secondary grouping should return 0", 0, df.getSecondaryGroupingSize());
        df.setSecondaryGroupingSize(3);
        assertEquals("Primary grouping should still return 3", 3, df.getGroupingSize());
        assertEquals("Secondary grouping should round-trip", 3, df.getSecondaryGroupingSize());
        df.setGroupingSize(4);
        assertEquals("Primary grouping should return 4", 4, df.getGroupingSize());
        assertEquals("Secondary should remember explicit setting and return 3", 3, df.getSecondaryGroupingSize());
    }

    @Test
    public void Test13074() {
        DecimalFormat df = (DecimalFormat) NumberFormat.getCurrencyInstance(new ULocale("bg-BG"));
        String result = df.format(987654.321);
        assertEquals("Locale 'bg' should not use monetary grouping", "987654,32 лв.", result);
    }

    @Test
    public void Test13088and13162() {
        ULocale loc = new ULocale("fa");
        String pattern1 = "%\u00A0#,##0;%\u00A0-#,##0";
        double num = -12.34;
        DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(loc);
        // If the symbols ever change in locale data, please call the setters so that this test
        // continues to use the old symbols.
        // The fa percent symbol does change in CLDR 32, so....
        symbols.setPercentString("‎٪");
        assertEquals("Checking for expected symbols", "‎−", symbols.getMinusSignString());
        assertEquals("Checking for expected symbols", "‎٪", symbols.getPercentString());
        DecimalFormat numfmt = new DecimalFormat(pattern1, symbols);
        expect2(numfmt, num, "‎٪ ‎−۱٬۲۳۴");
        String pattern2 = "%#,##0;%-#,##0";
        numfmt = new DecimalFormat(pattern2, symbols);
        expect2(numfmt, num, "‎٪‎−۱٬۲۳۴");
    }

    @Test
    public void Test13113_MalformedPatterns() {
        String[][] cases = {
                {"'", "quoted literal"},
                {"ab#c'd", "quoted literal"},
                {"ab#c*", "unquoted literal"},
                {"0#", "# cannot follow 0"},
                {".#0", "0 cannot follow #"},
                {"@0", "Cannot mix @ and 0"},
                {"0@", "Cannot mix 0 and @"},
                {"#x#", "unquoted special character"},
                {"@#@", "# inside of a run of @"},
        };
        for (String[] cas : cases) {
            try {
                new DecimalFormat(cas[0]);
                fail("Should have thrown on malformed pattern");
            } catch (IllegalArgumentException ex) {
                assertTrue("Exception should contain \"Malformed pattern\": " + ex.getMessage(),
                        ex.getMessage().contains("Malformed pattern"));
                assertTrue("Exception should contain \"" + cas[1] + "\"" + ex.getMessage(),
                        ex.getMessage().contains(cas[1]));
            }
        }
    }

    @Test
    public void Test13118() {
        DecimalFormat df = new DecimalFormat("@@@");
        df.setScientificNotation(true);
        for (double d=12345.67; d>1e-6; d/=10) {
            String result = df.format(d);
            assertEquals("Should produce a string of expected length on " + d,
                    d > 1 ? 6 : 7, result.length());
        }
    }

    @Test
    public void Test13289() {
        DecimalFormat df = new DecimalFormat("#00.0#E0");
        String result = df.format(0.00123);
        assertEquals("Should ignore scientific minInt if maxInt>minInt", "1.23E-3", result);
    }

    @Test
    public void Test13310() {
        // Note: if minInt > 8, then maxInt can be greater than 8.
        assertEquals("Should not throw an assertion error",
                "100000007.6E-1",
                new DecimalFormat("000000000.0#E0").format(10000000.76d));
    }

    @Test
    public void Test13391() throws ParseException {
        DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(new ULocale("ccp"));
        df.setParseStrict(true);
        String expected = "\uD804\uDD37\uD804\uDD38,\uD804\uDD39\uD804\uDD3A\uD804\uDD3B";
        assertEquals("Should produce expected output in ccp", expected, df.format(12345));
        Number result = df.parse(expected);
        assertEquals("Should parse to 12345 in ccp", 12345, result.longValue());

        df = (DecimalFormat) NumberFormat.getScientificInstance(new ULocale("ccp"));
        df.setParseStrict(true);
        String expectedScientific = "\uD804\uDD37.\uD804\uDD39E\uD804\uDD38";
        assertEquals("Should produce expected scientific output in ccp",
                expectedScientific, df.format(130));
        Number resultScientific = df.parse(expectedScientific);
        assertEquals("Should parse scientific to 130 in ccp",
                130, resultScientific.longValue());
    }

    @Test
    public void Test13453_AffixContent() {
        DecimalFormat df = (DecimalFormat) DecimalFormat.getScientificInstance();
        assertEquals("Scientific should NOT be included", "", df.getPositiveSuffix());

        df = CompactDecimalFormat.getInstance(ULocale.ENGLISH, CompactDecimalFormat.CompactStyle.SHORT);
        assertEquals("Compact should NOT be included", "", df.getPositiveSuffix());

        df = (DecimalFormat) DecimalFormat.getInstance(NumberFormat.ISOCURRENCYSTYLE);
        df.setCurrency(Currency.getInstance("GBP"));
        assertEquals("ISO currency SHOULD be included", "GBP", df.getPositivePrefix());

        df = (DecimalFormat) DecimalFormat.getInstance(NumberFormat.PLURALCURRENCYSTYLE);
        df.setCurrency(Currency.getInstance("GBP"));
        assertEquals("Plural name SHOULD be included", " British pounds", df.getPositiveSuffix());
    }

    @Test
    public void Test11035_FormatCurrencyAmount() {
        double amount = 12345.67;
        String expected = "12,345$67 ​";
        Currency cur = Currency.getInstance("PTE");

        // Test three ways to set currency via API

        ULocale loc1 = new ULocale("pt_PT");
        NumberFormat fmt1 = NumberFormat.getCurrencyInstance(loc1);
        fmt1.setCurrency(cur);
        String actualSetCurrency = fmt1.format(amount);

        ULocale loc2 = new ULocale("pt_PT@currency=PTE");
        NumberFormat fmt2 = NumberFormat.getCurrencyInstance(loc2);
        String actualLocaleString = fmt2.format(amount);

        ULocale loc3 = new ULocale("pt_PT");
        NumberFormat fmt3 = NumberFormat.getCurrencyInstance(loc3);
        CurrencyAmount curAmt = new CurrencyAmount(amount, cur);
        String actualCurrencyAmount = fmt3.format(curAmt);

        assertEquals("Custom Currency Pattern, Set Currency", expected, actualSetCurrency);
        assertEquals("Custom Currency Pattern, Locale String", expected, actualCurrencyAmount);
        assertEquals("Custom Currency Pattern, CurrencyAmount", expected, actualLocaleString);
    }

    @Test
    public void testPercentZero() {
        DecimalFormat df = (DecimalFormat) NumberFormat.getPercentInstance();
        String actual = df.format(0);
        assertEquals("Should have one zero digit", "0%", actual);
    }

    @Test
    public void testCurrencyZeroRounding() {
        DecimalFormat df = (DecimalFormat) NumberFormat.getCurrencyInstance();
        df.setMaximumFractionDigits(0);
        String actual = df.format(0);
        assertEquals("Should have zero fraction digits", "$0", actual);
    }

    @Test
    public void testCustomCurrencySymbol() {
        DecimalFormat df = (DecimalFormat) NumberFormat.getCurrencyInstance();
        df.setCurrency(Currency.getInstance("USD"));
        DecimalFormatSymbols symbols = df.getDecimalFormatSymbols();
        symbols.setCurrencySymbol("#");
        df.setDecimalFormatSymbols(symbols);
        String actual = df.format(123);
        assertEquals("Should use '#' instad of '$'", "# 123.00", actual);
    }

    @Test
    public void TestBasicSerializationRoundTrip() throws IOException, ClassNotFoundException {
        DecimalFormat df0 = new DecimalFormat("A-**#####,#00.00b¤");

        // Write to byte stream
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(df0);
        oos.flush();
        baos.close();
        byte[] bytes = baos.toByteArray();

        // Read from byte stream
        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
        Object obj = ois.readObject();
        ois.close();
        DecimalFormat df1 = (DecimalFormat) obj;

        // Test equality
        assertEquals("Did not round-trip through serialization", df0, df1);

        // Test basic functionality
        String str0 = df0.format(12345.67);
        String str1 = df1.format(12345.67);
        assertEquals("Serialized formatter does not produce same output", str0, str1);
    }

    @Test
    public void testGetSetCurrency() {
        DecimalFormat df = new DecimalFormat("¤#", DecimalFormatSymbols.getInstance(ULocale.US));
        assertEquals("Currency should start out as the locale default", Currency.getInstance("USD"), df.getCurrency());
        Currency curr = Currency.getInstance("EUR");
        df.setCurrency(curr);
        assertEquals("Currency should equal EUR after set", curr, df.getCurrency());
        String result = df.format(123);
        assertEquals("Currency should format as expected in EUR", "€123.00", result);
    }

    @Test
    public void testRoundingModeSetters() {
        DecimalFormat df1 = new DecimalFormat();
        DecimalFormat df2 = new DecimalFormat();

        df1.setRoundingMode(java.math.BigDecimal.ROUND_CEILING);
        assertNotEquals("Rounding mode was set to a non-default", df1, df2);
        df2.setRoundingMode(com.ibm.icu.math.BigDecimal.ROUND_CEILING);
        assertEquals("Rounding mode from icu.math and java.math should be the same", df1, df2);
        df2.setRoundingMode(java.math.RoundingMode.CEILING.ordinal());
        assertEquals("Rounding mode ordinal from java.math.RoundingMode should be the same", df1, df2);
    }

    @Test
    public void testCurrencySignificantDigits() {
        ULocale locale = new ULocale("en-US");
        DecimalFormat df = (DecimalFormat) NumberFormat.getCurrencyInstance(locale);
        df.setMaximumSignificantDigits(2);
        String result = df.format(1234);
        assertEquals("Currency rounding should obey significant digits", "$1,200", result);
    }

    @Test
    public void testParseStrictScientific() {
        // See ticket #13057
        DecimalFormat df = (DecimalFormat) NumberFormat.getScientificInstance();
        df.setParseStrict(true);
        ParsePosition ppos = new ParsePosition(0);
        Number result0 = df.parse("123E4", ppos);
        assertEquals("Should accept number with exponent", 1230000L, result0);
        assertEquals("Should consume the whole number", 5, ppos.getIndex());
        ppos.setIndex(0);
        result0 = df.parse("123", ppos);
        // #13737: For backwards compatibility, do NOT require the exponent.
        assertEquals("Should NOT reject number without exponent", 123L, result0);
        ppos.setIndex(0);
        CurrencyAmount result1 = df.parseCurrency("USD123", ppos);
        assertEquals("Should NOT reject currency without exponent",
                new CurrencyAmount(123L, Currency.getInstance("USD")),
                result1);
    }

    @Test
    public void testParseLenientScientific() {
        DecimalFormat df = (DecimalFormat) NumberFormat.getScientificInstance();
        ParsePosition ppos = new ParsePosition(0);
        Number result0 = df.parse("123E", ppos);
        assertEquals("Should parse the number in lenient mode", 123L, result0);
        assertEquals("Should stop before the E", 3, ppos.getIndex());
        DecimalFormatSymbols dfs = df.getDecimalFormatSymbols();
        dfs.setExponentSeparator("EE");
        df.setDecimalFormatSymbols(dfs);
        ppos.setIndex(0);
        result0 = df.parse("123EE", ppos);
        assertEquals("Should parse the number in lenient mode", 123L, result0);
        assertEquals("Should stop before the EE", 3, ppos.getIndex());
    }

    @Test
    public void testParseAcceptAsciiPercentPermilleFallback() {
        ULocale loc = new ULocale("ar");
        DecimalFormat df = (DecimalFormat) NumberFormat.getPercentInstance(loc);
        ParsePosition ppos = new ParsePosition(0);
        Number result = df.parse("42%", ppos);
        assertEquals("Should parse as 0.42 even in ar", new BigDecimal("0.42"), result);
        assertEquals("Should consume the entire string even in ar", 3, ppos.getIndex());
        // TODO: Is there a better way to make a localized permille formatter?
        df.applyPattern(df.toPattern().replace("%", "‰"));
        ppos.setIndex(0);
        result = df.parse("42‰", ppos);
        assertEquals("Should parse as 0.042 even in ar", new BigDecimal("0.042"), result);
        assertEquals("Should consume the entire string even in ar", 3, ppos.getIndex());
    }

    @Test
    public void testParseSubtraction() {
        // TODO: Is this a case we need to support? It prevents us from automatically parsing
        // minus signs that appear after the number, like  in "12-" vs "-12".
        DecimalFormat df = new DecimalFormat();
        String str = "12 - 5";
        ParsePosition ppos = new ParsePosition(0);
        Number n1 = df.parse(str, ppos);
        Number n2 = df.parse(str, ppos);
        assertEquals("Should parse 12 and -5", 12, n1.intValue());
        assertEquals("Should parse 12 and -5", -5, n2.intValue());
    }

    @Test
    public void testSetPrefixDefaultSuffix() {
        DecimalFormat df = (DecimalFormat) NumberFormat.getPercentInstance();
        df.setPositivePrefix("+");
        assertEquals("Should have manual plus sign and auto percent sign", "+100%", df.format(1));
    }

    @Test
    public void testMultiCodePointPaddingInPattern() {
        DecimalFormat df = new DecimalFormat("a*'நி'###0b");
        String result = df.format(12);
        assertEquals("Multi-codepoint padding should not be split", "aநிநி12b", result);
        df = new DecimalFormat("a*😁###0b");
        result = df.format(12);
        assertEquals("Single-codepoint padding should not be split", "a😁😁12b", result);
        df = new DecimalFormat("a*''###0b");
        result = df.format(12);
        assertEquals("Quote should be escapable in padding syntax", "a''12b", result);
    }

    @Test
    public void Test13737_ParseScientificStrict() {
        NumberFormat df = NumberFormat.getScientificInstance(ULocale.ENGLISH);
        df.setParseStrict(true);
        // Parse Test: exponent is not required, even in strict mode
        expect(df, "1.2", 1.2);
    }

    // TODO: Investigate this test and re-enable if appropriate.
    @Test
    @Ignore
    public void testParseAmbiguousAffixes() {
        BigDecimal positive = new BigDecimal("0.0567");
        BigDecimal negative = new BigDecimal("-0.0567");
        DecimalFormat df = new DecimalFormat();
        df.setParseBigDecimal(true);

        String[] patterns = { "+0.00%;-0.00%", "+0.00%;0.00%", "0.00%;-0.00%" };
        String[] inputs = { "+5.67%", "-5.67%", "5.67%" };
        boolean[][] expectedPositive = {
                { true, false, true },
                { true, false, false },
                { true, false, true }
        };

        for (int i=0; i<patterns.length; i++) {
            String pattern = patterns[i];
            df.applyPattern(pattern);
            for (int j=0; j<inputs.length; j++) {
                String input = inputs[j];
                ParsePosition ppos = new ParsePosition(0);
                Number actual = df.parse(input, ppos);
                BigDecimal expected = expectedPositive[i][j] ? positive : negative;
                String message = "Pattern " + pattern + " with input " + input;
                assertEquals(message, expected, actual);
                assertEquals(message, input.length(), ppos.getIndex());
            }
        }
    }

    @Test
    public void testParseIgnorables() {
        // Also see the test case "test parse ignorables" in numberformattestspecification.txt
        DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance();
        dfs.setPercentString("\u200E%\u200E");
        DecimalFormat df = new DecimalFormat("0 %;-0a", dfs);
        ParsePosition ppos = new ParsePosition(0);
        Number result = df.parse("42\u200E%\u200E ", ppos);
        assertEquals("Should parse as percentage", new BigDecimal("0.42"), result);
        assertEquals("Should consume the trailing bidi since it is in the symbol", 5, ppos.getIndex());
        ppos.setIndex(0);
        result = df.parse("-42a\u200E ", ppos);
        assertEquals("Should parse as percent", -0.42, result.doubleValue());
        assertEquals("Should not consume the trailing bidi or whitespace", 4, ppos.getIndex());

        // A few more cases based on the docstring:
        expect(df, "42%", 0.42);
        expect(df, "42 %", 0.42);
        expect(df, "42   %", 0.42);
        expect(df, "42\u00A0%", 0.42);
    }

    @Test
    public void testCustomCurrencyUsageOverridesPattern() {
        DecimalFormat df = new DecimalFormat("#,##0.###");
        expect2(df, 1234, "1,234");
        df.setCurrencyUsage(CurrencyUsage.STANDARD);
        expect2(df, 1234, "1,234.00");
        df.setCurrencyUsage(null);
        expect2(df, 1234, "1,234");
    }

    @Test
    public void testCurrencyUsageFractionOverrides() {
        NumberFormat df = DecimalFormat.getCurrencyInstance(ULocale.US);
        expect2(df, 35.0, "$35.00");
        df.setMinimumFractionDigits(3);
        expect2(df, 35.0, "$35.000");
        df.setMaximumFractionDigits(3);
        expect2(df, 35.0, "$35.000");
        df.setMinimumFractionDigits(-1);
        expect2(df, 35.0, "$35.00");
        df.setMaximumFractionDigits(-1);
        expect2(df, 35.0, "$35.00");
    }

    @Test
    public void testParseVeryVeryLargeExponent() {
        DecimalFormat df = new DecimalFormat();
        ParsePosition ppos = new ParsePosition(0);

        Object[][] cases = {
                {"1.2E+1234567890", Double.POSITIVE_INFINITY},
                {"1.2E+999999999", new com.ibm.icu.math.BigDecimal("1.2E+999999999")},
                {"1.2E+1000000000", Double.POSITIVE_INFINITY},
                {"-1.2E+999999999", new com.ibm.icu.math.BigDecimal("-1.2E+999999999")},
                {"-1.2E+1000000000", Double.NEGATIVE_INFINITY},
                {"1.2E-999999999", new com.ibm.icu.math.BigDecimal("1.2E-999999999")},
                {"1.2E-1000000000", 0.0},
                {"-1.2E-999999999", new com.ibm.icu.math.BigDecimal("-1.2E-999999999")},
                {"-1.2E-1000000000", -0.0},

        };

        for (Object[] cas : cases) {
            ppos.setIndex(0);
            String input = (String) cas[0];
            Number expected = (Number) cas[1];
            Number actual = df.parse(input, ppos);
            assertEquals(input, expected, actual);
        }
    }

    @Test
    public void testStringMethodsNPE() {
        String[] npeMethods = {
                "applyLocalizedPattern",
                "applyPattern",
                "setNegativePrefix",
                "setNegativeSuffix",
                "setPositivePrefix",
                "setPositiveSuffix"
        };
        for (String npeMethod : npeMethods) {
            DecimalFormat df = new DecimalFormat();
            try {
                DecimalFormat.class.getDeclaredMethod(npeMethod, String.class).invoke(df, (String) null);
                fail("NullPointerException not thrown in method " + npeMethod);
            } catch (InvocationTargetException e) {
                assertTrue("Exception should be NullPointerException in method " + npeMethod,
                        e.getCause() instanceof NullPointerException);
            } catch (Exception e) {
                // Other reflection exceptions
                throw new AssertionError("Reflection error in method " + npeMethod + ": " + e.getMessage());
            }
        }

        // Also test the constructors
        try {
            new DecimalFormat(null);
            fail("NullPointerException not thrown in 1-parameter constructor");
        } catch (NullPointerException e) {
            // Expected
        }
        try {
            new DecimalFormat(null, new DecimalFormatSymbols());
            fail("NullPointerException not thrown in 2-parameter constructor");
        } catch (NullPointerException e) {
            // Expected
        }
        try {
            new DecimalFormat(null, new DecimalFormatSymbols(), CurrencyPluralInfo.getInstance(), 0);
            fail("NullPointerException not thrown in 4-parameter constructor");
        } catch (NullPointerException e) {
            // Expected
        }
    }

    @Test
    public void testParseNoExponent() throws ParseException {
        DecimalFormat df = new DecimalFormat();
        assertEquals("Parse no exponent has wrong default", false, df.isParseNoExponent());
        Number result1 = df.parse("123E4");
        df.setParseNoExponent(true);
        assertEquals("Parse no exponent getter is broken", true, df.isParseNoExponent());
        Number result2 = df.parse("123E4");
        assertEquals("Exponent did not parse before setParseNoExponent", result1, new Long(1230000));
        assertEquals("Exponent parsed after setParseNoExponent", result2, new Long(123));
    }

    @Test
    public void testMinimumGroupingDigits() {
        String[][] allExpected = {
                {"123", "123"},
                {"1,230", "1230"},
                {"12,300", "12,300"},
                {"1,23,000", "1,23,000"}
        };

        DecimalFormat df = new DecimalFormat("#,##,##0");
        assertEquals("Minimum grouping digits has wrong default", 1, df.getMinimumGroupingDigits());

        for (int l = 123, i=0; l <= 123000; l *= 10, i++) {
            df.setMinimumGroupingDigits(1);
            assertEquals("Minimum grouping digits getter is broken", 1, df.getMinimumGroupingDigits());
            String actual = df.format(l);
            assertEquals("Output is wrong for 1, "+i, allExpected[i][0], actual);
            df.setMinimumGroupingDigits(2);
            assertEquals("Minimum grouping digits getter is broken", 2, df.getMinimumGroupingDigits());
            actual = df.format(l);
            assertEquals("Output is wrong for 2, "+i, allExpected[i][1], actual);
        }

        String[] locales = {"en-US", "es"};
        int[] groupingDigits = {
          1,
          DecimalFormat.MINIMUM_GROUPING_DIGITS_AUTO,
          DecimalFormat.MINIMUM_GROUPING_DIGITS_MIN2
        };
        int[] values = {1000, 10000};
        String[] allExpected2 = {
          // locale: en-US
          "1,000", "10,000",  // minimumGroupingDigits = 1
          "1,000", "10,000",  // minimumGroupingDigits = MINIMUM_GROUPING_DIGITS_AUTO
          "1000" , "10,000",  // minimumGroupingDigits = MINIMUM_GROUPING_DIGITS_MIN2
          // locale: es
          "1.000", "10.000",  // minimumGroupingDigits = 1
          "1000",  "10.000",  // minimumGroupingDigits = MINIMUM_GROUPING_DIGITS_AUTO
          "1000",  "10.000"   // minimumGroupingDigits = MINIMUM_GROUPING_DIGITS_MIN2
        };

        int i = 0;
        for (String locale : locales) {
          for (int minimumGroupingDigits : groupingDigits) {
            for (int value : values) {
              NumberFormat f = NumberFormat.getInstance(new ULocale(locale));
              df = (DecimalFormat) f;
              df.setMinimumGroupingDigits(minimumGroupingDigits);
              String actual = df.format(value);
              String expected = allExpected2[i++];
              assertEquals("Output is wrong for " + value +
                  " locale=" + locale + " minimumGroupingDigits=" + minimumGroupingDigits,
                  expected, actual);
            }
          }
        }

    }

    @Test
    public void testParseCaseSensitive() {
        String[] patterns = {"a#b", "A#B"};
        String[] inputs = {"a500b", "A500b", "a500B", "a500e10b", "a500E10b"};
        int[][] expectedParsePositions = {
                {5, 5, 5, 8, 8}, // case insensitive, pattern 0
                {5, 0, 4, 4, 8}, // case sensitive, pattern 0
                {5, 5, 5, 8, 8}, // case insensitive, pattern 1
                {0, 4, 0, 0, 0}, // case sensitive, pattern 1
        };

        for (int p = 0; p < patterns.length; p++) {
            String pat = patterns[p];
            DecimalFormat df = new DecimalFormat(pat);
            assertEquals("parseCaseSensitive default is wrong", false, df.isParseCaseSensitive());
            for (int i = 0; i < inputs.length; i++) {
                String inp = inputs[i];
                df.setParseCaseSensitive(false);
                assertEquals("parseCaseSensitive getter is broken", false, df.isParseCaseSensitive());
                ParsePosition actualInsensitive = new ParsePosition(0);
                df.parse(inp, actualInsensitive);
                assertEquals("Insensitive, pattern "+p+", input "+i,
                        expectedParsePositions[p*2][i], actualInsensitive.getIndex());
                df.setParseCaseSensitive(true);
                assertEquals("parseCaseSensitive getter is broken", true, df.isParseCaseSensitive());
                ParsePosition actualSensitive = new ParsePosition(0);
                df.parse(inp, actualSensitive);
                assertEquals("Sensitive, pattern "+p+", input "+i,
                        expectedParsePositions[p*2+1][i], actualSensitive.getIndex());
            }
        }
    }

    @Test
    public void testPlusSignAlwaysShown() throws ParseException {
        double[] numbers = {0.012, 5.78, 0, -0.012, -5.78};
        ULocale[] locs = {new ULocale("en-US"), new ULocale("ar-EG"), new ULocale("es-CL")};
        String[][][] expecteds = {
                // en-US
                {
                    // decimal
                    { "+0.012", "+5.78", "+0", "-0.012", "-5.78" },
                    // currency
                    { "+$0.01", "+$5.78", "+$0.00", "-$0.01", "-$5.78" }
                },
                // ar-EG (interesting because the plus sign string starts with \u061C)
                {
                    // decimal
                    {
                        "\u061C+\u0660\u066B\u0660\u0661\u0662", // "؜+٠٫٠١٢"
                        "\u061C+\u0665\u066B\u0667\u0668", // "؜+٥٫٧٨"
                        "\u061C+\u0660", // "؜+٠"
                        "\u061C-\u0660\u066B\u0660\u0661\u0662", // "؜-٠٫٠١٢"
                        "\u061C-\u0665\u066B\u0667\u0668", // "؜-٥٫٧٨"
                    },
                    // currency (\062C.\0645.\200F is the currency sign in ar for EGP)
                    {
                        "\u061C+\u0660\u066B\u0660\u0661\u00A0\u062C.\u0645.\u200F",
                        "\u061C+\u0665\u066B\u0667\u0668\u00A0\u062C.\u0645.\u200F",
                        "\u061C+\u0660\u066B\u0660\u0660\u00A0\u062C.\u0645.\u200F",
                        "\u061C-\u0660\u066B\u0660\u0661\u00A0\u062C.\u0645.\u200F",
                        "\u061C-\u0665\u066B\u0667\u0668\u00A0\u062C.\u0645.\u200F"
                    }
                },
                // es-CL (interesting because of position of sign in currency)
                {
                    // decimal
                    { "+0,012", "+5,78", "+0", "-0,012", "-5,78" },
                    // currency (note: rounding for es-CL's currency, CLP, is 0 fraction digits)
                    { "$+0", "$+6", "$+0", "$-0", "$-6" }
                }
        };

        for (int i=0; i<locs.length; i++) {
            ULocale loc = locs[i];
            DecimalFormat df1 = (DecimalFormat) NumberFormat.getNumberInstance(loc);
            assertFalse("Default should be false", df1.isSignAlwaysShown());
            df1.setSignAlwaysShown(true);
            assertTrue("Getter should now return true", df1.isSignAlwaysShown());
            DecimalFormat df2 = (DecimalFormat) NumberFormat.getCurrencyInstance(loc);
            assertFalse("Default should be false", df2.isSignAlwaysShown());
            df2.setSignAlwaysShown(true);
            assertTrue("Getter should now return true", df2.isSignAlwaysShown());
            for (int j=0; j<2; j++) {
                DecimalFormat df = (j == 0) ? df1 : df2;
                for (int k=0; k<numbers.length; k++) {
                    double d = numbers[k];
                    String exp = expecteds[i][j][k];
                    String act = df.format(d);
                    assertEquals("Locale " + loc + ", type " + j + ", " + d, exp, act);
                    BigDecimal parsedExp = BigDecimal.valueOf(d);
                    if (j == 1) {
                        // Currency-round expected parse output
                        int scale = (i == 2) ? 0 : 2;
                        parsedExp = parsedExp.setScale(scale, BigDecimal.ROUND_HALF_EVEN);
                    }
                    Number parsedNum = df.parse(exp);
                    BigDecimal parsedAct = (parsedNum.getClass() == BigDecimal.class)
                            ? (BigDecimal) parsedNum
                            : BigDecimal.valueOf(parsedNum.doubleValue());
                    assertEquals(
                            "Locale " + loc + ", type " + j + ", " + d + ", " + parsedExp + " => " + parsedAct,
                            0, parsedExp.compareTo(parsedAct));
                }
            }
        }
    }

    @Test
    public void Test20073_StrictPercentParseErrorIndex() {
        ParsePosition parsePosition = new ParsePosition(0);
        DecimalFormat df = new DecimalFormat("0%", DecimalFormatSymbols.getInstance(Locale.US));
        df.setParseStrict(true);
        Number number = df.parse("%2%", parsePosition);
        assertNull("", number);
        assertEquals("", 0, parsePosition.getIndex());
        assertEquals("", 0, parsePosition.getErrorIndex());
    }

    @Test
    public void Test11626_CustomizeCurrencyPluralInfo() throws ParseException {
        // Use locale sr because it has interesting plural rules.
        ULocale locale = ULocale.forLanguageTag("sr");
        DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(locale);
        CurrencyPluralInfo info = CurrencyPluralInfo.getInstance(locale);
        info.setCurrencyPluralPattern("one", "0 qwerty");
        info.setCurrencyPluralPattern("few", "0 dvorak");
        DecimalFormat df = new DecimalFormat("#", symbols, info, NumberFormat.CURRENCYSTYLE);
        df.setCurrency(Currency.getInstance("USD"));
        df.setMaximumFractionDigits(0);

        assertEquals("Plural one", "1 qwerty", df.format(1));
        assertEquals("Plural few", "3 dvorak", df.format(3));
        assertEquals("Plural other", "99 америчких долара", df.format(99));

        info.setPluralRules("few: n is 1; one: n in 2..4");
        df.setCurrencyPluralInfo(info);
        assertEquals("Plural one", "1 dvorak", df.format(1));
        assertEquals("Plural few", "3 qwerty", df.format(3));
        assertEquals("Plural other", "99 америчких долара", df.format(99));
    }

    @Test
    public void TestNarrowCurrencySymbols() {
        DecimalFormat df = (DecimalFormat) NumberFormat.getCurrencyInstance(ULocale.CANADA);
        df.setCurrency(Currency.getInstance("USD"));
        expect2(df, 123.45, "US$123.45");
        String pattern = df.toPattern();
        pattern = pattern.replace("¤", "¤¤¤¤¤");
        df.applyPattern(pattern);
        // Note: Narrow currency is not parseable because of ambiguity.
        assertEquals("Narrow currency symbol for USD in en_CA is $",
                "$123.45", df.format(123.45));
    }

    @Test
    public void TestAffixOverrideBehavior() {
        DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(ULocale.ENGLISH);
        expect2(df, 100, "100");
        expect2(df, -100, "-100");
        // This is not the right way to set an override plus sign, but we need to support it for compatibility.
        df.setPositivePrefix("+");
        expect2(df, 100, "+100");
        expect2(df, -100, "-100"); // note: the positive prefix does not affect the negative prefix
        df.applyPattern("a0");
        expect2(df, 100, "a100");
        expect2(df, -100, "-a100");
    }

    @Test
    public void TestCurrencyRoundingMinWithoutMax() {
        NumberFormat currencyFormat = DecimalFormat.getCurrencyInstance(Locale.US);
        currencyFormat.setCurrency(Currency.getInstance("AUD"));
        currencyFormat.setMinimumFractionDigits(0);
        expect(currencyFormat, 0.001, "A$0");

        // NOTE: The size of the increment takes precedent over minFrac since ICU 59.
        // CAD-Cash uses nickel rounding.
        currencyFormat = DecimalFormat.getCurrencyInstance(Locale.US);
        currencyFormat.setCurrency(Currency.getInstance("CAD"));
        ((DecimalFormat)currencyFormat).setCurrencyUsage(CurrencyUsage.CASH);
        currencyFormat.setMinimumFractionDigits(0);
        // expect(currencyFormat, 0.08, "CA$0.1");  // ICU 58 and down
        expect(currencyFormat, 0.08, "CA$0.10");  // ICU 59 and up
    }

    @Test
    public void testParsePositionIncrease() {
        String input = "123\n456\n$789";
        ParsePosition ppos = new ParsePosition(0);
        DecimalFormat df = new DecimalFormat();
        df.parse(input, ppos);
        assertEquals("Should stop after first entry", 3, ppos.getIndex());
        ppos.setIndex(ppos.getIndex() + 1);
        df.parse(input, ppos);
        assertEquals("Should stop after second entry", 7, ppos.getIndex());
        ppos.setIndex(ppos.getIndex() + 1);
        df.parseCurrency(input, ppos); // test parseCurrency API as well
        assertEquals("Should stop after third entry", 12, ppos.getIndex());
    }

    @Test
    public void testTrailingMinusSign() {
        String input = "52-";
        DecimalFormat df = (DecimalFormat) DecimalFormat.getInstance(ULocale.ENGLISH);
        ParsePosition ppos = new ParsePosition(0);
        Number result = df.parse(input, ppos);
        assertEquals("Trailing sign should NOT be accepted after the number in English by default",
                52.0,
                result.doubleValue(),
                0.0);
        df.applyPattern("#;#-");
        ppos.setIndex(0);
        result = df.parse(input, ppos);
        assertEquals("Trailing sign SHOULD be accepted if there is one in the pattern",
                -52.0,
                result.doubleValue(),
                0.0);
    }

    @Test
    public void testScientificCustomSign() {
        DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(ULocale.ENGLISH);
        dfs.setMinusSignString("nnn");
        dfs.setPlusSignString("ppp");
        DecimalFormat df = new DecimalFormat("0E0", dfs);
        df.setExponentSignAlwaysShown(true);
        expect2(df, 0.5, "5Ennn1");
        expect2(df, 50, "5Eppp1");
    }

    @Test
    public void testParsePercentInPattern() {
        DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(ULocale.ENGLISH);
        DecimalFormat df = new DecimalFormat("0x%", dfs);
        df.setParseStrict(true);
        expect2(df, 0.5, "50x%");
    }

    @Test
    public void testParseIsoStrict() {
        DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(ULocale.ENGLISH);
        DecimalFormat df = new DecimalFormat("¤¤0;-0¤¤", dfs);
        df.setCurrency(Currency.getInstance("USD"));
        df.setParseStrict(true);
        expect2(df, 45, "USD 45.00");
        expect2(df, -45, "-45.00 USD");
    }

    @Test
    public void test13684_FrenchPercentParsing() {
        NumberFormat numberFormat = NumberFormat.getPercentInstance(ULocale.FRENCH);
        numberFormat.setParseStrict(true);
        ParsePosition ppos = new ParsePosition(0);
        Number percentage = numberFormat.parse("8\u00A0%", ppos);
        assertEquals("Should parse successfully", 0.08, percentage.doubleValue());
        assertEquals("Should consume whole string", 3, ppos.getIndex());
    }

    @Test
    public void testStrictParseCurrencyLongNames() {
        DecimalFormat df = (DecimalFormat) DecimalFormat.getInstance(ULocale.ENGLISH, DecimalFormat.PLURALCURRENCYSTYLE);
        df.setParseStrict(true);
        df.setCurrency(Currency.getInstance("USD"));
        double input = 514.23;
        String formatted = df.format(input);
        String expected = "514.23 US dollars";
        assertEquals("Should format as expected", expected, formatted);
        ParsePosition ppos = new ParsePosition(0);
        CurrencyAmount ca = df.parseCurrency(formatted, ppos);
        assertEquals("Should consume whole number", ppos.getIndex(), 17);
        assertEquals("Number should round-trip", ca.getNumber().doubleValue(), input);
        assertEquals("Should get correct currency", ca.getCurrency().getCurrencyCode(), "USD");
        // Should also round-trip in non-currency parsing
        expect2(df, input, expected);
    }

    @Test
    public void testStrictParseCurrencySpacing() {
        DecimalFormat df = new DecimalFormat("¤ 0", DecimalFormatSymbols.getInstance(ULocale.ROOT));
        df.setCurrency(Currency.getInstance("USD"));
        df.setParseStrict(true);
        expect2(df, -51.42, "-US$ 51.42");
    }

    @Test
    public void testCaseSensitiveCustomIsoCurrency() {
        DecimalFormat df = new DecimalFormat("¤¤0", DecimalFormatSymbols.getInstance(ULocale.ENGLISH));
        df.setCurrency(Currency.getInstance("ICU"));
        ParsePosition ppos = new ParsePosition(0);
        df.parseCurrency("icu123", ppos);
        assertEquals("Should succeed", 6, ppos.getIndex());
        assertEquals("Should succeed", -1, ppos.getErrorIndex());
    }

    @Test
    public void testCurrencyPluralAffixOverrides() {
        // The affix setters should override CurrencyPluralInfo, used in the plural currency constructor.
        DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(ULocale.ENGLISH, NumberFormat.PLURALCURRENCYSTYLE);
        assertEquals("Defaults to unknown currency", " (unknown currency)", df.getPositiveSuffix());
        df.setCurrency(Currency.getInstance("USD"));
        assertEquals("Should resolve to CurrencyPluralInfo", " US dollars", df.getPositiveSuffix());
        df.setPositiveSuffix("lala");
        assertEquals("Custom suffix should round-trip", "lala", df.getPositiveSuffix());
        assertEquals("Custom suffix should be used in formatting", "123.00lala", df.format(123));
    }

    @Test
    public void testParseDoubleMinus() {
        DecimalFormat df = new DecimalFormat("-0", DecimalFormatSymbols.getInstance(ULocale.ENGLISH));
        expect2(df, -5, "--5");
    }

    @Test
    public void testParsePercentRegression() {
        DecimalFormat df1 = (DecimalFormat) NumberFormat.getInstance(ULocale.ENGLISH);
        DecimalFormat df2 = (DecimalFormat) NumberFormat.getPercentInstance(ULocale.ENGLISH);
        df1.setParseStrict(false);
        df2.setParseStrict(false);

        {
            ParsePosition ppos = new ParsePosition(0);
            Number result = df1.parse("50%", ppos);
            assertEquals("df1 should accept a number but not the percent sign", 2, ppos.getIndex());
            assertEquals("df1 should return the number as 50", 50.0, result.doubleValue());
        }
        {
            ParsePosition ppos = new ParsePosition(0);
            Number result = df2.parse("50%", ppos);
            assertEquals("df2 should accept the percent sign", 3, ppos.getIndex());
            assertEquals("df2 should return the number as 0.5", 0.5, result.doubleValue());
        }
        {
            ParsePosition ppos = new ParsePosition(0);
            Number result = df2.parse("50", ppos);
            assertEquals("df2 should return the number as 0.5 even though the percent sign is missing",
                    0.5,
                    result.doubleValue());
        }
    }

    @Test
    public void test13148_GroupingSeparatorOverride() throws Exception {
        DecimalFormat fmt = (DecimalFormat)NumberFormat.getInstance(new ULocale("en", "ZA"));
        DecimalFormatSymbols symbols = fmt.getDecimalFormatSymbols();
        symbols.setDecimalSeparator('.');
        symbols.setGroupingSeparator(',');
        fmt.setDecimalFormatSymbols(symbols);
        Number number = fmt.parse("300,000");
        assertEquals("Should use custom symbols and not monetary symbols", 300000L, number);
    }

    @Test
    public void test11897_LocalizedPatternSeparator() {
        DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(ULocale.ENGLISH);
        dfs.setPatternSeparator('!');
        DecimalFormat df = new DecimalFormat("0", dfs);
        df.applyPattern("a0;b0"); // should not throw
        assertEquals("should apply the normal pattern", df.getNegativePrefix(), "b");
        df.applyLocalizedPattern("c0!d0"); // should not throw
        assertEquals("should apply the localized pattern", df.getNegativePrefix(), "d");
    }

    @Test
    public void test13777_ParseLongNameNonCurrencyMode() {
        // Currency long name should round-trip even when non-currency parsing is used.
        NumberFormat df = NumberFormat.getInstance(ULocale.US, NumberFormat.PLURALCURRENCYSTYLE);
        expect2(df, 1.5, "1.50 US dollars");
    }

    @Test
    public void test13804_EmptyStringsWhenParsing() {
        DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(ULocale.ENGLISH);
        dfs.setCurrencySymbol("");
        dfs.setDecimalSeparatorString("");
        dfs.setDigitStrings(new String[] { "", "", "", "", "", "", "", "", "", "" });
        dfs.setExponentMultiplicationSign("");
        dfs.setExponentSeparator("");
        dfs.setGroupingSeparatorString("");
        dfs.setInfinity("");
        dfs.setInternationalCurrencySymbol("");
        dfs.setMinusSignString("");
        dfs.setMonetaryDecimalSeparatorString("");
        dfs.setMonetaryGroupingSeparatorString("");
        dfs.setNaN("");
        dfs.setPatternForCurrencySpacing(DecimalFormatSymbols.CURRENCY_SPC_INSERT, false, "");
        dfs.setPatternForCurrencySpacing(DecimalFormatSymbols.CURRENCY_SPC_INSERT, true, "");
        dfs.setPercentString("");
        dfs.setPerMillString("");
        dfs.setPlusSignString("");

        DecimalFormat df = new DecimalFormat("0", dfs);
        df.setGroupingUsed(true);
        df.setScientificNotation(true);
        df.setParseStrict(false); // enable all matchers
        df.format(0); // should not throw or hit infinite loop
        String[] samples = new String[] {
                "",
                "123",
                "$123",
                "-",
                "+",
                "44%",
                "1E+2.3"
        };
        for (String sample : samples) {
            logln("Attempting parse on: " + sample);
            // We don't care about the results, only that we don't throw and don't loop.
            ParsePosition ppos = new ParsePosition(0);
            df.parse(sample, ppos);
            ppos = new ParsePosition(0);
            df.parseCurrency(sample, ppos);
        }

        // Test with a nonempty exponent separator symbol to cover more code
        dfs.setExponentSeparator("E");
        df.setDecimalFormatSymbols(dfs);
        {
            ParsePosition ppos = new ParsePosition(0);
            df.parse("1E+2.3", ppos);
        }
    }

    @Test
    public void Test20037_ScientificIntegerOverflow() throws ParseException {
        NumberFormat nf = NumberFormat.getInstance(ULocale.US);

        // Test overflow of exponent
        Number result = nf.parse("1E-2147483648");
        assertEquals("Should snap to zero",
                "0", result.toString());

        // Test edge case overflow of exponent
        // Note: the behavior is different from C++; this is probably due to the
        // intermediate BigDecimal form, which has its own restrictions
        result = nf.parse("1E-2147483647E-1");
        assertEquals("Should not overflow and should parse only the first exponent",
                "0.0", result.toString());

        // For Java, we should get *pretty close* to 2^31.
        result = nf.parse("1E-547483647");
        assertEquals("Should *not* snap to zero",
                "1E-547483647", result.toString());

        // Test edge case overflow of exponent
        result = nf.parse(".0003e-2147483644");
        assertEquals("Should not overflow",
                "0", result.toString());

        // Test largest parseable exponent
        // This is limited by ICU's BigDecimal implementation
        result = nf.parse("1e999999999");
        assertEquals("Should not overflow",
                "1E+999999999", result.toString());

        // Test max value as well
        String[] infinityInputs = {
                "9876e1000000000",
                "9876e2147483640",
                "9876e2147483641",
                "9876e2147483642",
                "9876e2147483643",
                "9876e2147483644",
                "9876e2147483645",
                "9876e2147483646",
                "9876e2147483647",
                "9876e2147483648",
                "9876e2147483649",
        };
        for (String input : infinityInputs) {
            result = nf.parse(input);
            assertEquals("Should become Infinity: " + input,
                    "Infinity", result.toString());
        }
    }

    @Test
    public void test13840_ParseLongStringCrash() throws ParseException {
        NumberFormat nf = NumberFormat.getInstance(ULocale.ENGLISH);
        String bigString =
            "111111111111111111111111111111111111111111111111111111111111111111111" +
            "111111111111111111111111111111111111111111111111111111111111111111111" +
            "111111111111111111111111111111111111111111111111111111111111111111111" +
            "111111111111111111111111111111111111111111111111111111111111111111111" +
            "111111111111111111111111111111111111111111111111111111111111111111111" +
            "111111111111111111111111111111111111111111111111111111111111111111111";
        Number result = nf.parse(bigString);

        // Normalize the input string:
        BigDecimal expectedBigDecimal = new BigDecimal(bigString);
        String expectedUString = expectedBigDecimal.toString();

        // Get the output string:
        BigDecimal actualBigDecimal = (BigDecimal) result;
        String actualUString = actualBigDecimal.toString();

        assertEquals("Should round-trip without crashing", expectedUString, actualUString);
    }

    @Test
    public void test20348_CurrencyPrefixOverride() {
        DecimalFormat fmt = (DecimalFormat) NumberFormat.getCurrencyInstance(ULocale.ENGLISH);
        assertEquals("Initial pattern",
            "¤#,##0.00", fmt.toPattern());
        assertEquals("Initial prefix",
            "¤", fmt.getPositivePrefix());
        assertEquals("Initial suffix",
            "-¤", fmt.getNegativePrefix());
        assertEquals("Initial format",
            "\u00A4100.00", fmt.format(100));

        fmt.setPositivePrefix("$");
        assertEquals("Set positive prefix pattern",
            "$#,##0.00;-\u00A4#,##0.00", fmt.toPattern());
        assertEquals("Set positive prefix prefix",
            "$", fmt.getPositivePrefix());
        assertEquals("Set positive prefix suffix",
            "-¤", fmt.getNegativePrefix());
        assertEquals("Set positive prefix format",
            "$100.00", fmt.format(100));

        fmt.setNegativePrefix("-$");
        assertEquals("Set negative prefix pattern",
            "$#,##0.00;'-'$#,##0.00", fmt.toPattern());
        assertEquals("Set negative prefix prefix",
            "$", fmt.getPositivePrefix());
        assertEquals("Set negative prefix suffix",
            "-$", fmt.getNegativePrefix());
        assertEquals("Set negative prefix format",
            "$100.00", fmt.format(100));
    }

    @Test
    public void test20956_MonetarySymbolGetters() {
        Locale locale = new Locale.Builder().setLocale(Locale.forLanguageTag("et")).build();
        DecimalFormat decimalFormat = (DecimalFormat) NumberFormat.getCurrencyInstance(locale);
        Currency currency = Currency.getInstance("EEK");

        decimalFormat.setCurrency(currency);

        DecimalFormatSymbols decimalFormatSymbols = decimalFormat.getDecimalFormatSymbols();
        assertEquals("MONETARY DECIMAL SEPARATOR", ".", decimalFormatSymbols.getMonetaryDecimalSeparatorString());
        assertEquals("DECIMAL SEPARATOR", ",", decimalFormatSymbols.getDecimalSeparatorString());
        assertEquals("MONETARY GROUPING SEPARATOR", " ", decimalFormatSymbols.getMonetaryGroupingSeparatorString());
        assertEquals("GROUPING SEPARATOR", " ", decimalFormatSymbols.getGroupingSeparatorString());
        assertEquals("CURRENCY SYMBOL", "kr", decimalFormatSymbols.getCurrencySymbol());

        StringBuffer sb = new StringBuffer();
        decimalFormat.format(new BigDecimal(12345.12), sb, DontCareFieldPosition.INSTANCE);
        assertEquals("OUTPUT", "12 345.12 kr", sb.toString());
    }

    @Test
    public void test20358_GroupingInPattern() {
        DecimalFormat fmt = (DecimalFormat) NumberFormat.getInstance(ULocale.ENGLISH);
        assertEquals("Initial pattern",
            "#,##0.###", fmt.toPattern());
        assertTrue("Initial grouping",
            fmt.isGroupingUsed());
        assertEquals("Initial format",
            "54,321", fmt.format(54321));

        fmt.setGroupingUsed(false);
        assertEquals("Set grouping false",
            "0.###", fmt.toPattern());
        assertFalse("Set grouping false grouping",
            fmt.isGroupingUsed());
        assertEquals("Set grouping false format",
            "54321", fmt.format(54321));

        fmt.setGroupingUsed(true);
        assertEquals("Set grouping true",
            "#,##0.###", fmt.toPattern());
        assertTrue("Set grouping true grouping",
            fmt.isGroupingUsed());
        assertEquals("Set grouping true format",
            "54,321", fmt.format(54321));
    }

    @Test
    public void test13731_DefaultCurrency() {
        {
            NumberFormat nf = NumberFormat.getInstance(ULocale.ENGLISH, NumberFormat.CURRENCYSTYLE);
            assertEquals("symbol", "¤1.10", nf.format(1.1));
            assertEquals("currency", "XXX", nf.getCurrency().getCurrencyCode());
        }
        {
            NumberFormat nf = NumberFormat.getInstance(ULocale.ENGLISH, NumberFormat.ISOCURRENCYSTYLE);
            assertEquals("iso_code", "XXX 1.10", nf.format(1.1));
            assertEquals("currency", "XXX", nf.getCurrency().getCurrencyCode());
        }
        {
            NumberFormat nf = NumberFormat.getInstance(ULocale.ENGLISH, NumberFormat.PLURALCURRENCYSTYLE);
            assertEquals("plural", "1.10 (unknown currency)", nf.format(1.1));
            assertEquals("currency", "XXX", nf.getCurrency().getCurrencyCode());
        }
    }

    @Test
    public void test20499_CurrencyVisibleDigitsPlural() {
        ULocale locale = new ULocale("ro-RO");
        NumberFormat nf = NumberFormat.getInstance(locale, NumberFormat.PLURALCURRENCYSTYLE);
        String expected = "24,00 lei românești";
        for (int i=0; i<5; i++) {
            String actual = nf.format(24);
            assertEquals("iteration " + i, expected, actual);
        }
    }

    @Test
    public void test13735_GroupingSizeGetter() {
        DecimalFormatSymbols EN = DecimalFormatSymbols.getInstance(ULocale.ENGLISH);
        {
            DecimalFormat df = new DecimalFormat("0", EN);
            assertEquals("pat 0: ", 0, df.getGroupingSize());
            df.setGroupingUsed(false);
            assertEquals("pat 0 then disabled: ", 0, df.getGroupingSize());
            df.setGroupingUsed(true);
            assertEquals("pat 0 then enabled: ", 0, df.getGroupingSize());
        }
        {
            DecimalFormat df = new DecimalFormat("#,##0", EN);
            assertEquals("pat #,##0: ", 3, df.getGroupingSize());
            df.setGroupingUsed(false);
            assertEquals("pat #,##0 then disabled: ", 3, df.getGroupingSize());
            df.setGroupingUsed(true);
            assertEquals("pat #,##0 then enabled: ", 3, df.getGroupingSize());
        }
    }

    @Test
    public void test13734_StrictFlexibleWhitespace() {
        DecimalFormatSymbols EN = DecimalFormatSymbols.getInstance(ULocale.ENGLISH);
        {
          DecimalFormat df = new DecimalFormat("+0", EN);
          df.setParseStrict(true);
          ParsePosition ppos = new ParsePosition(0);
          Number result = df.parse("+  33", ppos);
          assertEquals("ppos: ", 0, ppos.getIndex());
          assertEquals("result: ", null, result);
        }
        {
          DecimalFormat df = new DecimalFormat("+ 0", EN);
          df.setParseStrict(true);
          ParsePosition ppos = new ParsePosition(0);
          Number result = df.parse("+  33", ppos);
          assertEquals("ppos: ", 0, ppos.getIndex());
          assertEquals("result: ", null, result);
        }
    }

    @Test
    public void test20961_CurrencyPluralPattern() {
        DecimalFormat decimalFormat = (DecimalFormat) NumberFormat.getInstance(ULocale.US, NumberFormat.PLURALCURRENCYSTYLE);
        assertEquals("Currency pattern", "#,##0.00 ¤¤¤", decimalFormat.toPattern());
    }

    @Test
    public void test13733_StrictAndLenient() {
        Object[][] cases = { {"CA$ 12", "¤ 0", 12, 12},
                {"CA$12", "¤0", 12, 12},
                {"CAD 12", "¤¤ 0", 12, 12},
                {"12 CAD", "0 ¤¤", 12, 12},
                {"12 Canadian dollars", "0 ¤¤¤", 12, 12},
                {"$12 ", "¤¤¤¤0", 12, 12},
                {"12$", "0¤¤¤¤", 12, 12},
                {"CA$ 12", "¤0", 0, 12},
                {"CA$ 12", "0 ¤¤", 0, 12},
                {"CA$ 12", "0 ¤¤¤", 0, 12},
                {"CA$ 12", "¤¤¤¤0", 0, 12},
                {"CA$ 12", "0¤¤¤¤", 0, 12},
                {"CA$12", "¤ 0", 0, 12},
                {"CA$12", "¤¤ 0", 0, 12},
                {"CA$12", "0 ¤¤", 0, 12},
                {"CA$12", "0 ¤¤¤", 0, 12},
                {"CA$12", "0¤¤¤¤", 0, 12},
                {"CAD 12", "¤0", 0, 12},
                {"CAD 12", "0 ¤¤", 0, 12},
                {"CAD 12", "0 ¤¤¤", 0, 12},
                {"CAD 12", "¤¤¤¤0", 0, 12},
                {"CAD 12", "0¤¤¤¤", 0, 12},
                {"12 CAD", "¤ 0", 0, 12},
                {"12 CAD", "¤0", 0, 12},
                {"12 CAD", "¤¤ 0", 0, 12},
                {"12 CAD", "¤¤¤¤0", 0, 12},
                {"12 CAD", "0¤¤¤¤", 0, 12},
                {"12 Canadian dollars", "¤ 0", 0, 12},
                {"12 Canadian dollars", "¤0", 0, 12},
                {"12 Canadian dollars", "¤¤ 0", 0, 12},
                {"12 Canadian dollars", "¤¤¤¤0", 0, 12},
                {"12 Canadian dollars", "0¤¤¤¤", 0, 12},
                {"$12 ", "¤ 0", 0, 12},
                {"$12 ", "¤¤ 0", 0, 12},
                {"$12 ", "0 ¤¤", 0, 12},
                {"$12 ", "0 ¤¤¤", 0, 12},
                {"$12 ", "0¤¤¤¤", 0, 12},
                {"12$", "¤ 0", 0, 12},
                {"12$", "¤0", 0, 12},
                {"12$", "¤¤ 0", 0, 12},
                {"12$", "0 ¤¤", 0, 12},
                {"12$", "0 ¤¤¤", 0, 12},
                {"12$", "¤¤¤¤0", 0, 12} };

        for (Object[] cas : cases) {
            String inputString = (String) cas[0];
            String patternString = (String) cas[1];
            int expectedStrictParse = (int) cas[2];
            int expectedLenientParse = (int) cas[3];

            int parsedStrictValue = 0;
            int parsedLenientValue = 0;
            ParsePosition ppos = new ParsePosition(0);
            DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(ULocale.ENGLISH);
            DecimalFormat df = new DecimalFormat(patternString, dfs);

            df.setParseStrict(true);
            CurrencyAmount ca_strict = df.parseCurrency(inputString, ppos);
            if (null != ca_strict) {
                parsedStrictValue = ca_strict.getNumber().intValue();
            }
            assertEquals("Strict parse of " + inputString + " using " + patternString,
                    parsedStrictValue, expectedStrictParse);

            ppos.setIndex(0);
            df.setParseStrict(false);
            CurrencyAmount ca_lenient = df.parseCurrency(inputString, ppos);
            if (null != ca_lenient) {
                parsedLenientValue = ca_lenient.getNumber().intValue();
            }
            assertEquals("Strict parse of " + inputString + " using " + patternString,
                    parsedLenientValue, expectedLenientParse);
        }
    }
}
