// © 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.dev.text.DecimalFormat_ICU58;
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.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 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", "\uFFE51,234.56", "CNY 1,234.56", "\u4EBA\u6C11\u5E01 1,234.56"},
                {"zh_CN", "\u00A4#,##0.00;(\u00A4#,##0.00)", "-1234.56", "(\uFFE51,234.56)", "(CNY 1,234.56)", "(\u4EBA\u6C11\u5E01 1,234.56)"},
                {"zh_CN", "\u00A4#,##0.00;(\u00A4#,##0.00)", "1", "\uFFE51.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, "XXX\u00A01.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", "PREEURO", "1,50\u00a0DM",
                "fr", "FR", "", "1,50\u00a0\u20AC",
                "fr", "FR", "PREEURO", "1,50\u00a0F",
        };

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

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

            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+3])) {
                logln("Ok: 1.50 x " + locale + " => " + sCurr);
            } else {
                errln("FAIL: 1.50 x " + locale + " => " + sCurr +
                        ", expected " + DATA[i+3]);
            }
        }

        //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", "4", "-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 234,56 \u20AC");

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

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

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

        expectCurrency(fmt, Currency.getInstance(Locale.FRANCE),
                1234.56, "1 234,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");
    }

    /**
     * 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[] standardPatterns58 = { "#,##0.05+%;#,##0.05-%", "* @@@E0‰;* -@@@E0‰" };
        String[] localizedPatterns = { "▰⁖▰▰໐⁘໐໕†⁜⁙▰⁖▰▰໐⁘໐໕‡⁜", "⁂ ⁕⁕⁕⁑⁑໐‱" };
        String[] localizedPatterns58 = { "▰⁖▰▰໐⁘໐໕+⁜⁙▰⁖▰▰໐⁘໐໕‡⁜", "⁂ ⁕⁕⁕⁑⁑໐‱⁙⁂ ‡⁕⁕⁕⁑⁑໐‱" };

        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 standardPattern58 = standardPatterns58[i];
            String localizedPattern = localizedPatterns[i];
            String localizedPattern58 = localizedPatterns58[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());

            // Android can't access DecimalFormat_ICU58 for testing (ticket #13283).
            if (TestUtil.getJavaVendor() == TestUtil.JavaVendor.Android) continue;

            // Note: ICU 58 does not support plus signs in patterns
            // Note: ICU 58 always prints the negative part of scientific notation patterns,
            //       even when the negative part is not necessary
            DecimalFormat_ICU58 df3 = new DecimalFormat_ICU58("#", dfs);
            df3.applyPattern(standardPattern); // Reading standardPattern is OK
            DecimalFormat_ICU58 df4 = new DecimalFormat_ICU58("#", dfs);
            df4.applyLocalizedPattern(localizedPattern58);
            // Note: DecimalFormat#equals() is broken on ICU 58
            assertEquals("toPattern should match on ICU58 localizedPattern instance",
                    standardPattern58, df4.toPattern());
            assertEquals("toLocalizedPattern should match on ICU58 standardPattern instance",
                    localizedPattern58, df3.toLocalizedPattern());
        }
    }

    @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 {
            boolean latnFound = false;
            for (String name : availableNames){
                if ("latn".equals(name)) {
                    latnFound = true;
                    break;
                }
            }

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

        // 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
    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" },
        };
        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);
        }
    }

    @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 switches from 0 decimals to 2; PKR 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 = "PKR 124";
            DecimalFormat custom = null;
            if (i == 0) {
                custom = (DecimalFormat) DecimalFormat.getInstance(new ULocale("en_US@currency=PKR"),
                        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=PKR"),
                        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 = "PKR 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<FieldContainer>();
        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<FieldContainer>(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<FieldContainer>(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<FieldContainer>(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<FieldContainer>(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);
        try {
            df.setMathContext(unlimitedCeiling);
            df.parse(hugeNumberString);
            fail("Extreme division with unlimitedCeiling 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.getParseNoExponent());
        Number result1 = df.parse("123E4");
        df.setParseNoExponent(true);
        assertEquals("Parse no exponent getter is broken", true, df.getParseNoExponent());
        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);
        }
    }

    @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.getParseCaseSensitive());
            for (int i = 0; i < inputs.length; i++) {
                String inp = inputs[i];
                df.setParseCaseSensitive(false);
                assertEquals("parseCaseSensitive getter is broken", false, df.getParseCaseSensitive());
                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.getParseCaseSensitive());
                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.getSignAlwaysShown());
            df1.setSignAlwaysShown(true);
            assertTrue("Getter should now return true", df1.getSignAlwaysShown());
            DecimalFormat df2 = (DecimalFormat) NumberFormat.getCurrencyInstance(loc);
            assertFalse("Default should be false", df2.getSignAlwaysShown());
            df2.setSignAlwaysShown(true);
            assertTrue("Getter should now return true", df2.getSignAlwaysShown());
            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 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 fail to parse", 0, ppos.getIndex());
        assertEquals("Should fail to parse", 0, 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 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);
    }
}
