]> gitweb.fperrin.net Git - Dictionary.git/blobdiff - jars/icu4j-4_2_1-src/src/com/ibm/icu/dev/test/format/RbnfTest.java
go
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / icu / dev / test / format / RbnfTest.java
old mode 100755 (executable)
new mode 100644 (file)
index 618c6ff..f8a0fe3
-//##header\r
-/*\r
- *******************************************************************************\r
- * Copyright (C) 1996-2009, International Business Machines Corporation and    *\r
- * others. All Rights Reserved.                                                *\r
- *******************************************************************************\r
- */\r
-package com.ibm.icu.dev.test.format;\r
-\r
-import java.math.BigInteger;\r
-import java.text.DecimalFormat;\r
-import java.text.NumberFormat;\r
-import java.text.ParseException;\r
-import java.util.Locale;\r
-import java.util.Random;\r
-\r
-import com.ibm.icu.dev.test.TestFmwk;\r
-import com.ibm.icu.text.RuleBasedNumberFormat;\r
-import com.ibm.icu.util.ULocale;\r
-\r
-public class RbnfTest extends TestFmwk {\r
-    public static void main(String[] args) {\r
-        RbnfTest test = new RbnfTest();\r
-\r
-        try {\r
-            test.run(args);\r
-        }\r
-        catch (Throwable e) {\r
-            System.out.println("Entire test failed because of exception: "\r
-                               + e.toString());\r
-            e.printStackTrace();\r
-        }\r
-    }\r
-\r
-    static String fracRules = \r
-        "%main:\n" +\r
-        // this rule formats the number if it's 1 or more.  It formats\r
-        // the integral part using a DecimalFormat ("#,##0" puts\r
-        // thousands separators in the right places) and the fractional\r
-        // part using %%frac.  If there is no fractional part, it\r
-        // just shows the integral part.\r
-        "    x.0: <#,##0<[ >%%frac>];\n" +\r
-        // this rule formats the number if it's between 0 and 1.  It\r
-        // shows only the fractional part (0.5 shows up as "1/2," not\r
-        // "0 1/2")\r
-        "    0.x: >%%frac>;\n" +\r
-        // the fraction rule set.  This works the same way as the one in the\r
-        // preceding example: We multiply the fractional part of the number\r
-        // being formatted by each rule's base value and use the rule that\r
-        // produces the result closest to 0 (or the first rule that produces 0).\r
-        // Since we only provide rules for the numbers from 2 to 10, we know\r
-        // we'll get a fraction with a denominator between 2 and 10.\r
-        // "<0<" causes the numerator of the fraction to be formatted\r
-        // using numerals\r
-        "%%frac:\n" +\r
-        "    2: 1/2;\n" +\r
-        "    3: <0</3;\n" +\r
-        "    4: <0</4;\n" +\r
-        "    5: <0</5;\n" +\r
-        "    6: <0</6;\n" +\r
-        "    7: <0</7;\n" +\r
-        "    8: <0</8;\n" +\r
-        "    9: <0</9;\n" +\r
-        "   10: <0</10;\n";\r
-\r
-    static {\r
-        // mondo hack\r
-    char[] fracRulesArr = fracRules.toCharArray();\r
-        int len = fracRulesArr.length;\r
-        int change = 2;\r
-        for (int i = 0; i < len; ++i) {\r
-            char ch = fracRulesArr[i];\r
-            if (ch == '\n') {\r
-                change = 2; // change ok\r
-            } else if (ch == ':') {\r
-                change = 1; // change, but once we hit a non-space char, don't change\r
-            } else if (ch == ' ') {\r
-                if (change != 0) {\r
-                    fracRulesArr[i] = (char)0x200e;\r
-                }\r
-            } else {\r
-                if (change == 1) {\r
-                    change = 0;\r
-                }\r
-            }\r
-        }\r
-    fracRules = new String(fracRulesArr);\r
-    }\r
-\r
-    static final String durationInSecondsRules =\r
-        // main rule set for formatting with words\r
-        "%with-words:\n"\r
-        // take care of singular and plural forms of "second"\r
-        + "    0 seconds; 1 second; =0= seconds;\n"\r
-        // use %%min to format values greater than 60 seconds\r
-        + "    60/60: <%%min<[, >>];\n"\r
-        // use %%hr to format values greater than 3,600 seconds\r
-        // (the ">>>" below causes us to see the number of minutes\r
-        // when when there are zero minutes)\r
-        + "    3600/60: <%%hr<[, >>>];\n"\r
-        // this rule set takes care of the singular and plural forms\r
-        // of "minute"\r
-        + "%%min:\n"\r
-        + "    0 minutes; 1 minute; =0= minutes;\n"\r
-        // this rule set takes care of the singular and plural forms\r
-        // of "hour"\r
-        + "%%hr:\n"\r
-        + "    0 hours; 1 hour; =0= hours;\n"\r
-\r
-        // main rule set for formatting in numerals\r
-        + "%in-numerals:\n"\r
-        // values below 60 seconds are shown with "sec."\r
-        + "    =0= sec.;\n"\r
-        // higher values are shown with colons: %%min-sec is used for\r
-        // values below 3,600 seconds...\r
-        + "    60: =%%min-sec=;\n"\r
-        // ...and %%hr-min-sec is used for values of 3,600 seconds\r
-        // and above\r
-        + "    3600: =%%hr-min-sec=;\n"\r
-        // this rule causes values of less than 10 minutes to show without\r
-        // a leading zero\r
-        + "%%min-sec:\n"\r
-        + "    0: :=00=;\n"\r
-        + "    60/60: <0<>>;\n"\r
-        // this rule set is used for values of 3,600 or more.  Minutes are always\r
-        // shown, and always shown with two digits\r
-        + "%%hr-min-sec:\n"\r
-        + "    0: :=00=;\n"\r
-        + "    60/60: <00<>>;\n"\r
-        + "    3600/60: <#,##0<:>>>;\n"\r
-        // the lenient-parse rules allow several different characters to be used\r
-        // as delimiters between hours, minutes, and seconds\r
-        + "%%lenient-parse:\n"\r
-        + "    & : = . = ' ' = -;\n";\r
-\r
-    public void TestCoverage() {\r
-        // extra calls to boost coverage numbers\r
-        RuleBasedNumberFormat fmt0 = new RuleBasedNumberFormat(RuleBasedNumberFormat.SPELLOUT);\r
-        RuleBasedNumberFormat fmt1 = (RuleBasedNumberFormat)fmt0.clone();\r
-        RuleBasedNumberFormat fmt2 = new RuleBasedNumberFormat(RuleBasedNumberFormat.SPELLOUT);\r
-        if (!fmt0.equals(fmt0)) {\r
-            errln("self equality fails");\r
-        }\r
-        if (!fmt0.equals(fmt1)) {\r
-            errln("clone equality fails");\r
-        }\r
-        if (!fmt0.equals(fmt2)) {\r
-            errln("duplicate equality fails");\r
-        }\r
-        String str = fmt0.toString();\r
-        logln(str);\r
-\r
-        RuleBasedNumberFormat fmt3 =  new RuleBasedNumberFormat(durationInSecondsRules);\r
-\r
-        if (fmt0.equals(fmt3)) {\r
-            errln("nonequal fails");\r
-        }\r
-        if (!fmt3.equals(fmt3)) {\r
-            errln("self equal 2 fails");\r
-        }\r
-        str = fmt3.toString();\r
-        logln(str);\r
-\r
-        String[] names = fmt3.getRuleSetNames();\r
-\r
-        try {\r
-            fmt3.setDefaultRuleSet(null);\r
-            fmt3.setDefaultRuleSet("%%foo");\r
-            errln("sdrf %%foo didn't fail");\r
-        }\r
-        catch (Exception e) {\r
-            logln("Got the expected exception");\r
-        }\r
-\r
-        try {\r
-            fmt3.setDefaultRuleSet("%bogus");\r
-            errln("sdrf %bogus didn't fail");\r
-        }\r
-        catch (Exception e) {\r
-            logln("Got the expected exception");\r
-        }\r
-\r
-        try {\r
-            str = fmt3.format(2.3, names[0]);\r
-            logln(str);\r
-            str = fmt3.format(2.3, "%%foo");\r
-            errln("format double %%foo didn't fail");\r
-        }\r
-        catch (Exception e) {\r
-            logln("Got the expected exception");\r
-        }\r
-\r
-        try {\r
-            str = fmt3.format(123L, names[0]);\r
-            logln(str);\r
-            str = fmt3.format(123L, "%%foo");\r
-            errln("format double %%foo didn't fail");\r
-        }\r
-        catch (Exception e) {\r
-            logln("Got the expected exception");\r
-        }\r
-\r
-        RuleBasedNumberFormat fmt4 = new RuleBasedNumberFormat(fracRules, Locale.ENGLISH);\r
-        RuleBasedNumberFormat fmt5 = new RuleBasedNumberFormat(fracRules, Locale.ENGLISH);\r
-        str = fmt4.toString();\r
-        logln(str);\r
-        if (!fmt4.equals(fmt5)) {\r
-            errln("duplicate 2 equality failed");\r
-        }\r
-        str = fmt4.format(123L);\r
-        logln(str);\r
-        try {\r
-            Number num = fmt4.parse(str);\r
-            logln(num.toString());\r
-        }\r
-        catch (Exception e) {\r
-            errln("parse caught exception");\r
-        }\r
-\r
-        str = fmt4.format(.000123);\r
-        logln(str);\r
-        try {\r
-            Number num = fmt4.parse(str);\r
-            logln(num.toString());\r
-        }\r
-        catch (Exception e) {\r
-            errln("parse caught exception");\r
-        }\r
-\r
-        str = fmt4.format(456.000123);\r
-        logln(str);\r
-        try {\r
-            Number num = fmt4.parse(str);\r
-            logln(num.toString());\r
-        }\r
-        catch (Exception e) {\r
-            errln("parse caught exception");\r
-        }\r
-    }\r
-\r
-    public void TestUndefinedSpellout() {\r
-        Locale greek = new Locale("el", "", "");\r
-        RuleBasedNumberFormat[] formatters = {\r
-            new RuleBasedNumberFormat(greek, RuleBasedNumberFormat.SPELLOUT),\r
-            new RuleBasedNumberFormat(greek, RuleBasedNumberFormat.ORDINAL),\r
-            new RuleBasedNumberFormat(greek, RuleBasedNumberFormat.DURATION),\r
-        };\r
-\r
-        String[] data = {\r
-            "0",\r
-            "1",\r
-            "15",\r
-            "20",\r
-            "23",\r
-            "73",\r
-            "88",\r
-            "100",\r
-            "106",\r
-            "127",\r
-            "200",\r
-            "579",\r
-            "1,000",\r
-            "2,000",\r
-            "3,004",\r
-            "4,567",\r
-            "15,943",\r
-            "105,000",\r
-            "2,345,678",\r
-            "-36",\r
-            "-36.91215",\r
-            "234.56789"\r
-        };\r
-\r
-        NumberFormat decFormat = NumberFormat.getInstance(Locale.US);\r
-        for (int j = 0; j < formatters.length; ++j) {\r
-            com.ibm.icu.text.NumberFormat formatter = formatters[j];\r
-            logln("formatter[" + j + "]");\r
-            for (int i = 0; i < data.length; ++i) {\r
-                try {\r
-                    String result = formatter.format(decFormat.parse(data[i]));\r
-                    logln("[" + i + "] " + data[i] + " ==> " + result);\r
-                }\r
-                catch (Exception e) {\r
-                    errln("formatter[" + j + "], data[" + i + "] " + data[i] + " threw exception " + e.getMessage());\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Perform a simple spot check on the English spellout rules\r
-     */\r
-    public void TestEnglishSpellout() {\r
-        RuleBasedNumberFormat formatter\r
-            = new RuleBasedNumberFormat(Locale.US,\r
-                                        RuleBasedNumberFormat.SPELLOUT);\r
-        String[][] testData = {\r
-            { "1", "one" },\r
-            { "15", "fifteen" },\r
-            { "20", "twenty" },\r
-            { "23", "twenty-three" },\r
-            { "73", "seventy-three" },\r
-            { "88", "eighty-eight" },\r
-            { "100", "one hundred" },\r
-            { "106", "one hundred six" },\r
-            { "127", "one hundred twenty-seven" },\r
-            { "200", "two hundred" },\r
-            { "579", "five hundred seventy-nine" },\r
-            { "1,000", "one thousand" },\r
-            { "2,000", "two thousand" },\r
-            { "3,004", "three thousand four" },\r
-            { "4,567", "four thousand five hundred sixty-seven" },\r
-            { "15,943", "fifteen thousand nine hundred forty-three" },\r
-            { "2,345,678", "two million three hundred forty-five "\r
-              + "thousand six hundred seventy-eight" },\r
-            { "-36", "minus thirty-six" },\r
-            { "234.567", "two hundred thirty-four point five six seven" }\r
-        };\r
-\r
-        doTest(formatter, testData, true);\r
-\r
-        formatter.setLenientParseMode(true);\r
-        String[][] lpTestData = {\r
-            { "FOurhundred     thiRTY six", "436" },\r
-            // test spaces before fifty-7 causing lenient parse match of "fifty-" to " fifty"\r
-            // leaving "-7" for remaining parse, resulting in 2643 as the parse result.\r
-            { "fifty-7", "57" },\r
-            { " fifty-7", "57" },\r
-            { "  fifty-7", "57" },\r
-            { "2 thousand six HUNDRED   fifty-7", "2,657" },\r
-            { "fifteen hundred and zero", "1,500" }\r
-        };\r
-        doLenientParseTest(formatter, lpTestData);\r
-    }\r
-\r
-    /**\r
-     * Perform a simple spot check on the English ordinal-abbreviation rules\r
-     */\r
-    public void TestOrdinalAbbreviations() {\r
-        RuleBasedNumberFormat formatter\r
-            = new RuleBasedNumberFormat(Locale.US,\r
-                                        RuleBasedNumberFormat.ORDINAL);\r
-        String[][] testData = {\r
-            { "1", "1\u02e2\u1d57" },\r
-            { "2", "2\u207f\u1d48" },\r
-            { "3", "3\u02b3\u1d48" },\r
-            { "4", "4\u1d57\u02b0" },\r
-            { "7", "7\u1d57\u02b0" },\r
-            { "10", "10\u1d57\u02b0" },\r
-            { "11", "11\u1d57\u02b0" },\r
-            { "13", "13\u1d57\u02b0" },\r
-            { "20", "20\u1d57\u02b0" },\r
-            { "21", "21\u02e2\u1d57" },\r
-            { "22", "22\u207f\u1d48" },\r
-            { "23", "23\u02b3\u1d48" },\r
-            { "24", "24\u1d57\u02b0" },\r
-            { "33", "33\u02b3\u1d48" },\r
-            { "102", "102\u207f\u1d48" },\r
-            { "312", "312\u1d57\u02b0" },\r
-            { "12,345", "12,345\u1d57\u02b0" }\r
-        };\r
-\r
-        doTest(formatter, testData, false);\r
-    }\r
-\r
-    /**\r
-     * Perform a simple spot check on the duration-formatting rules\r
-     */\r
-    public void TestDurations() {\r
-        RuleBasedNumberFormat formatter\r
-            = new RuleBasedNumberFormat(Locale.US,\r
-                                        RuleBasedNumberFormat.DURATION);\r
-        String[][] testData = {\r
-            { "3,600", "1:00:00" },             //move me and I fail\r
-            { "0", "0 sec." },\r
-            { "1", "1 sec." },\r
-            { "24", "24 sec." },\r
-            { "60", "1:00" },\r
-            { "73", "1:13" },\r
-            { "145", "2:25" },\r
-            { "666", "11:06" },\r
-            //            { "3,600", "1:00:00" },\r
-            { "3,740", "1:02:20" },\r
-            { "10,293", "2:51:33" }\r
-        };\r
-\r
-        doTest(formatter, testData, true);\r
-\r
-        formatter.setLenientParseMode(true);\r
-        String[][] lpTestData = {\r
-            { "2-51-33", "10,293" }\r
-        };\r
-        doLenientParseTest(formatter, lpTestData);\r
-    }\r
-\r
-    /**\r
-     * Perform a simple spot check on the Spanish spellout rules\r
-     */\r
-    public void TestSpanishSpellout() {\r
-        RuleBasedNumberFormat formatter\r
-            = new RuleBasedNumberFormat(new Locale("es", "es",\r
-                                                   ""), RuleBasedNumberFormat.SPELLOUT);\r
-        String[][] testData = {\r
-            { "1", "uno" },\r
-            { "6", "seis" },\r
-            { "16", "diecis\u00e9is" },\r
-            { "20", "veinte" },\r
-            { "24", "veinticuatro" },\r
-            { "26", "veintis\u00e9is" },\r
-            { "73", "setenta y tres" },\r
-            { "88", "ochenta y ocho" },\r
-            { "100", "cien" },\r
-            { "106", "ciento seis" },\r
-            { "127", "ciento veintisiete" },\r
-            { "200", "doscientos" },\r
-            { "579", "quinientos setenta y nueve" },\r
-            { "1,000", "mil" },\r
-            { "2,000", "dos mil" },\r
-            { "3,004", "tres mil cuatro" },\r
-            { "4,567", "cuatro mil quinientos sesenta y siete" },\r
-            { "15,943", "quince mil novecientos cuarenta y tres" },\r
-            { "2,345,678", "dos millones trescientos cuarenta y cinco mil "\r
-              + "seiscientos setenta y ocho"},\r
-            { "-36", "menos treinta y seis" },\r
-            { "234.567", "doscientos treinta y cuatro coma cinco seis siete" }\r
-        };\r
-\r
-        doTest(formatter, testData, true);\r
-    }\r
-\r
-    /**\r
-     * Perform a simple spot check on the French spellout rules\r
-     */\r
-    public void TestFrenchSpellout() {\r
-        RuleBasedNumberFormat formatter\r
-            = new RuleBasedNumberFormat(Locale.FRANCE,\r
-                                        RuleBasedNumberFormat.SPELLOUT);\r
-        String[][] testData = {\r
-            { "1", "un" },\r
-            { "15", "quinze" },\r
-            { "20", "vingt" },\r
-            { "21", "vingt-et-un" },\r
-            { "23", "vingt-trois" },\r
-            { "62", "soixante-deux" },\r
-            { "70", "soixante-dix" },\r
-            { "71", "soixante-et-onze" },\r
-            { "73", "soixante-treize" },\r
-            { "80", "quatre-vingts" },\r
-            { "88", "quatre-vingt-huit" },\r
-            { "100", "cent" },\r
-            { "106", "cent-six" },\r
-            { "127", "cent-vingt-sept" },\r
-            { "200", "deux-cents" },\r
-            { "579", "cinq-cent-soixante-dix-neuf" },\r
-            { "1,000", "mille" },\r
-            { "1,123", "mille-cent-vingt-trois" },\r
-            { "1,594", "mille-cinq-cent-quatre-vingt-quatorze" },\r
-            { "2,000", "deux-mille" },\r
-            { "3,004", "trois-mille-quatre" },\r
-            { "4,567", "quatre-mille-cinq-cent-soixante-sept" },\r
-            { "15,943", "quinze-mille-neuf-cent-quarante-trois" },\r
-            { "2,345,678", "deux millions trois-cent-quarante-cinq-mille-"\r
-              + "six-cent-soixante-dix-huit" },\r
-            { "-36", "moins trente-six" },\r
-            { "234.567", "deux-cent-trente-quatre virgule cinq six sept" }\r
-        };\r
-\r
-        doTest(formatter, testData, true);\r
-\r
-        formatter.setLenientParseMode(true);\r
-        String[][] lpTestData = {\r
-            { "trente-et-un", "31" },\r
-            { "un cent quatre vingt dix huit", "198" }\r
-        };\r
-        doLenientParseTest(formatter, lpTestData);\r
-    }\r
-\r
-    /**\r
-     * Perform a simple spot check on the Swiss French spellout rules\r
-     */\r
-    public void TestSwissFrenchSpellout() {\r
-        RuleBasedNumberFormat formatter\r
-            = new RuleBasedNumberFormat(new Locale("fr", "CH",\r
-                                                   ""), RuleBasedNumberFormat.SPELLOUT);\r
-        String[][] testData = {\r
-            { "1", "un" },\r
-            { "15", "quinze" },\r
-            { "20", "vingt" },\r
-            { "21", "vingt-et-un" },\r
-            { "23", "vingt-trois" },\r
-            { "62", "soixante-deux" },\r
-            { "70", "septante" },\r
-            { "71", "septante-et-un" },\r
-            { "73", "septante-trois" },\r
-            { "80", "huitante" },\r
-            { "88", "huitante-huit" },\r
-            { "100", "cent" },\r
-            { "106", "cent-six" },\r
-            { "127", "cent-vingt-sept" },\r
-            { "200", "deux-cents" },\r
-            { "579", "cinq-cent-septante-neuf" },\r
-            { "1,000", "mille" },\r
-            { "1,123", "mille-cent-vingt-trois" },\r
-            { "1,594", "mille-cinq-cent-nonante-quatre" },\r
-            { "2,000", "deux-mille" },\r
-            { "3,004", "trois-mille-quatre" },\r
-            { "4,567", "quatre-mille-cinq-cent-soixante-sept" },\r
-            { "15,943", "quinze-mille-neuf-cent-quarante-trois" },\r
-            { "2,345,678", "deux millions trois-cent-quarante-cinq-mille-"\r
-              + "six-cent-septante-huit" },\r
-            { "-36", "moins trente-six" },\r
-            { "234.567", "deux-cent-trente-quatre virgule cinq six sept" }\r
-        };\r
-\r
-        doTest(formatter, testData, true);\r
-    }\r
-\r
-    /**\r
-     * Perform a simple spot check on the Italian spellout rules\r
-     */\r
-    public void TestItalianSpellout() {\r
-        RuleBasedNumberFormat formatter\r
-            = new RuleBasedNumberFormat(Locale.ITALIAN,\r
-                                        RuleBasedNumberFormat.SPELLOUT);\r
-        String[][] testData = {\r
-            { "1", "uno" },\r
-            { "15", "quindici" },\r
-            { "20", "venti" },\r
-            { "23", "venti\u00ADtr\u00E9" },\r
-            { "73", "settanta\u00ADtr\u00E9" },\r
-            { "88", "ottant\u00ADotto" },\r
-            { "100", "cento" },\r
-            { "106", "cento\u00ADsei" },\r
-            { "108", "cent\u00ADotto" },\r
-            { "127", "cento\u00ADventi\u00ADsette" },\r
-            { "181", "cent\u00ADottant\u00ADuno" },\r
-            { "200", "due\u00ADcento" },\r
-            { "579", "cinque\u00ADcento\u00ADsettanta\u00ADnove" },\r
-            { "1,000", "mille" },\r
-            { "2,000", "due\u00ADmila" },\r
-            { "3,004", "tre\u00ADmila\u00ADquattro" },\r
-            { "4,567", "quattro\u00ADmila\u00ADcinque\u00ADcento\u00ADsessanta\u00ADsette" },\r
-            { "15,943", "quindici\u00ADmila\u00ADnove\u00ADcento\u00ADquaranta\u00ADtr\u00E9" },\r
-            { "-36", "meno trenta\u00ADsei" },\r
-            { "234.567", "due\u00ADcento\u00ADtrenta\u00ADquattro virgola cinque sei sette" }\r
-        };\r
-\r
-        doTest(formatter, testData, true);\r
-    }\r
-\r
-    /**\r
-     * Perform a simple spot check on the German spellout rules\r
-     */\r
-    public void TestGermanSpellout() {\r
-        RuleBasedNumberFormat formatter\r
-            = new RuleBasedNumberFormat(Locale.GERMANY,\r
-                                        RuleBasedNumberFormat.SPELLOUT);\r
-        String[][] testData = {\r
-            { "1", "eins" },\r
-            { "15", "f\u00fcnfzehn" },\r
-            { "20", "zwanzig" },\r
-            { "23", "drei\u00ADund\u00ADzwanzig" },\r
-            { "73", "drei\u00ADund\u00ADsiebzig" },\r
-            { "88", "acht\u00ADund\u00ADachtzig" },\r
-            { "100", "ein\u00ADhundert" },\r
-            { "106", "ein\u00ADhundert\u00ADsechs" },\r
-            { "127", "ein\u00ADhundert\u00ADsieben\u00ADund\u00ADzwanzig" },\r
-            { "200", "zwei\u00ADhundert" },\r
-            { "579", "f\u00fcnf\u00ADhundert\u00ADneun\u00ADund\u00ADsiebzig" },\r
-            { "1,000", "ein\u00ADtausend" },\r
-            { "2,000", "zwei\u00ADtausend" },\r
-            { "3,004", "drei\u00ADtausend\u00ADvier" },\r
-            { "4,567", "vier\u00ADtausend\u00ADf\u00fcnf\u00ADhundert\u00ADsieben\u00ADund\u00ADsechzig" },\r
-            { "15,943", "f\u00fcnfzehn\u00ADtausend\u00ADneun\u00ADhundert\u00ADdrei\u00ADund\u00ADvierzig" },\r
-            { "2,345,678", "zwei Millionen drei\u00ADhundert\u00ADf\u00fcnf\u00ADund\u00ADvierzig\u00ADtausend\u00AD"\r
-              + "sechs\u00ADhundert\u00ADacht\u00ADund\u00ADsiebzig" }\r
-        };\r
-\r
-        doTest(formatter, testData, true);\r
-\r
-        formatter.setLenientParseMode(true);\r
-        String[][] lpTestData = {\r
-            { "ein Tausend sechs Hundert fuenfunddreissig", "1,635" }\r
-        };\r
-        doLenientParseTest(formatter, lpTestData);\r
-    }\r
-\r
-    /**\r
-     * Perform a simple spot check on the Thai spellout rules\r
-     */\r
-    public void TestThaiSpellout() {\r
-        RuleBasedNumberFormat formatter\r
-            = new RuleBasedNumberFormat(new Locale("th", "TH", ""),\r
-                                        RuleBasedNumberFormat.SPELLOUT);\r
-        String[][] testData = {\r
-            { "0", "\u0e28\u0e39\u0e19\u0e22\u0e4c" },\r
-            { "1", "\u0e2b\u0e19\u0e36\u0e48\u0e07" },\r
-            { "10", "\u0e2a\u0e34\u0e1a" },\r
-            { "11", "\u0e2a\u0e34\u0e1a\u200b\u0e40\u0e2d\u0e47\u0e14" },\r
-            { "21", "\u0e22\u0e35\u0e48\u200b\u0e2a\u0e34\u0e1a\u200b\u0e40\u0e2d\u0e47\u0e14" },\r
-            { "101", "\u0e2b\u0e19\u0e36\u0e48\u0e07\u200b\u0e23\u0e49\u0e2d\u0e22\u200b\u0e2b\u0e19\u0e36\u0e48\u0e07" },\r
-            { "1.234", "\u0e2b\u0e19\u0e36\u0e48\u0e07\u200b\u0e08\u0e38\u0e14\u200b\u0e2a\u0e2d\u0e07\u0e2a\u0e32\u0e21\u0e2a\u0e35\u0e48" },\r
-            { "21.45", "\u0e22\u0e35\u0e48\u200b\u0e2a\u0e34\u0e1a\u200b\u0e40\u0e2d\u0e47\u0e14\u200b\u0e08\u0e38\u0e14\u200b\u0e2a\u0e35\u0e48\u0e2b\u0e49\u0e32" },\r
-            { "22.45", "\u0e22\u0e35\u0e48\u200b\u0e2a\u0e34\u0e1a\u200b\u0e2a\u0e2d\u0e07\u200b\u0e08\u0e38\u0e14\u200b\u0e2a\u0e35\u0e48\u0e2b\u0e49\u0e32" },\r
-            { "23.45", "\u0e22\u0e35\u0e48\u200b\u0e2a\u0e34\u0e1a\u200b\u0e2a\u0e32\u0e21\u200b\u0e08\u0e38\u0e14\u200b\u0e2a\u0e35\u0e48\u0e2b\u0e49\u0e32" },\r
-            { "123.45", "\u0e2b\u0e19\u0e36\u0e48\u0e07\u200b\u0e23\u0e49\u0e2d\u0e22\u200b\u0e22\u0e35\u0e48\u200b\u0e2a\u0e34\u0e1a\u200b\u0e2a\u0e32\u0e21\u200b\u0e08\u0e38\u0e14\u200b\u0e2a\u0e35\u0e48\u0e2b\u0e49\u0e32" },\r
-            { "12,345.678", "\u0E2B\u0E19\u0E36\u0E48\u0E07\u200b\u0E2B\u0E21\u0E37\u0E48\u0E19\u200b\u0E2A\u0E2D\u0E07\u200b\u0E1E\u0E31\u0E19\u200b\u0E2A\u0E32\u0E21\u200b\u0E23\u0E49\u0E2D\u0E22\u200b\u0E2A\u0E35\u0E48\u200b\u0E2A\u0E34\u0E1A\u200b\u0E2B\u0E49\u0E32\u200b\u0E08\u0E38\u0E14\u200b\u0E2B\u0E01\u0E40\u0E08\u0E47\u0E14\u0E41\u0E1B\u0E14" },\r
-        };\r
-\r
-        doTest(formatter, testData, true);\r
-\r
-        /*\r
-          formatter.setLenientParseMode(true);\r
-          String[][] lpTestData = {\r
-          { "ein Tausend sechs Hundert fuenfunddreissig", "1,635" }\r
-          };\r
-          doLenientParseTest(formatter, lpTestData);\r
-        */\r
-    }\r
-\r
-    public void TestFractionalRuleSet() {\r
-\r
-\r
-        RuleBasedNumberFormat formatter =\r
-            new RuleBasedNumberFormat(fracRules, Locale.ENGLISH);\r
-\r
-        String[][] testData = {\r
-            { "0", "0" },\r
-            { "1", "1" },\r
-            { "10", "10" },\r
-            { ".1", "1/10" },\r
-            { ".11", "1/9" },\r
-            { ".125", "1/8" },\r
-            { ".1428", "1/7" },\r
-            { ".1667", "1/6" },\r
-            { ".2", "1/5" },\r
-            { ".25", "1/4" },\r
-            { ".333", "1/3" },\r
-            { ".5", "1/2" },\r
-            { "1.1", "1 1/10" },\r
-            { "2.11", "2 1/9" },\r
-            { "3.125", "3 1/8" },\r
-            { "4.1428", "4 1/7" },\r
-            { "5.1667", "5 1/6" },\r
-            { "6.2", "6 1/5" },\r
-            { "7.25", "7 1/4" },\r
-            { "8.333", "8 1/3" },\r
-            { "9.5", "9 1/2" },\r
-            { ".2222", "2/9" },\r
-            { ".4444", "4/9" },\r
-            { ".5555", "5/9" },\r
-            { "1.2856", "1 2/7" }\r
-        };\r
-        doTest(formatter, testData, false); // exact values aren't parsable from fractions\r
-    }\r
-\r
-    public void TestSwedishSpellout()\r
-    {\r
-        Locale locale = new Locale("sv", "", "");\r
-        RuleBasedNumberFormat formatter = new RuleBasedNumberFormat(locale, RuleBasedNumberFormat.SPELLOUT);\r
-\r
-        String[][] testDataDefault = {\r
-            { "101", "ett\u00ADhundra\u00ADett" },\r
-            { "123", "ett\u00ADhundra\u00ADtjugo\u00ADtre" },\r
-            { "1,001", "ettusen ett" },\r
-            { "1,100", "ettusen ett\u00ADhundra" },\r
-            { "1,101", "ettusen ett\u00ADhundra\u00ADett" },\r
-            { "1,234", "ettusen tv\u00e5\u00ADhundra\u00ADtrettio\u00ADfyra" },\r
-            { "10,001", "tio\u00ADtusen ett" },\r
-            { "11,000", "elva\u00ADtusen" },\r
-            { "12,000", "tolv\u00ADtusen" },\r
-            { "20,000", "tjugo-tusen" },\r
-            { "21,000", "tjugo\u00ADett-tusen" },\r
-            { "21,001", "tjugo\u00ADett-tusen ett" },\r
-            { "200,000", "tv\u00e5\u00ADhundra-tusen" },\r
-            { "201,000", "tv\u00e5\u00ADhundra\u00ADett-tusen" },\r
-            { "200,200", "tv\u00e5\u00ADhundra-tusen tv\u00e5\u00ADhundra" },\r
-            { "2,002,000", "tv\u00e5 miljoner tv\u00e5\u00ADtusen" },\r
-            { "12,345,678", "tolv miljoner tre\u00ADhundra\u00ADfyrtio\u00ADfem-tusen sex\u00ADhundra\u00ADsjuttio\u00AD\u00e5tta" },\r
-            { "123,456.789", "ett\u00ADhundra\u00ADtjugo\u00ADtre-tusen fyra\u00ADhundra\u00ADfemtio\u00ADsex komma sju \u00e5tta nio" },\r
-            { "-12,345.678", "minus tolv\u00ADtusen tre\u00ADhundra\u00ADfyrtio\u00ADfem komma sex sju \u00e5tta" }\r
-        };\r
-\r
-        logln("testing default rules");\r
-        doTest(formatter, testDataDefault, true);\r
-\r
-        String[][] testDataNeutrum = {\r
-            { "101", "ett\u00adhundra\u00aden" },\r
-            { "1,001", "ettusen en" },\r
-            { "1,101", "ettusen ett\u00adhundra\u00aden" },\r
-            { "10,001", "tio\u00adtusen en" },\r
-            { "21,001", "tjugo\u00aden\u00adtusen en" }\r
-        };\r
-\r
-        formatter.setDefaultRuleSet("%spellout-cardinal-neutre");\r
-        logln("testing neutrum rules");\r
-        doTest(formatter, testDataNeutrum, true);\r
-\r
-        String[][] testDataYear = {\r
-            { "101", "ett\u00adhundra\u00adett" },\r
-            { "900", "nio\u00adhundra" },\r
-            { "1,001", "ettusen ett" },\r
-            { "1,100", "elva\u00adhundra" },\r
-            { "1,101", "elva\u00adhundra\u00adett" },\r
-            { "1,234", "tolv\u00adhundra\u00adtrettio\u00adfyra" },\r
-            { "2,001", "tjugo\u00adhundra\u00adett" },\r
-            { "10,001", "tio\u00adtusen ett" }\r
-        };\r
-\r
-        formatter.setDefaultRuleSet("%spellout-numbering-year");\r
-        logln("testing year rules");\r
-        doTest(formatter, testDataYear, true);\r
-    }\r
-\r
-    public void TestBigNumbers() {\r
-        BigInteger bigI = new BigInteger("1234567890", 10);\r
-        StringBuffer buf = new StringBuffer();\r
-        RuleBasedNumberFormat fmt = new RuleBasedNumberFormat(RuleBasedNumberFormat.SPELLOUT);\r
-        fmt.format(bigI, buf, null);\r
-        logln("big int: " + buf.toString());\r
-\r
-//#if defined(FOUNDATION10)\r
-//#else\r
-        buf.setLength(0);\r
-        java.math.BigDecimal bigD = new java.math.BigDecimal(bigI);\r
-        fmt.format(bigD, buf, null);\r
-        logln("big dec: " + buf.toString());\r
-//#endif\r
-    }\r
-\r
-  public void TestTrailingSemicolon() {\r
-    String thaiRules = \r
-        "%default:\n" +\r
-        "  -x: \u0e25\u0e1a>>;\n" +\r
-        "  x.x: <<\u0e08\u0e38\u0e14>>>;\n" +\r
-        "  \u0e28\u0e39\u0e19\u0e22\u0e4c; \u0e2b\u0e19\u0e36\u0e48\u0e07; \u0e2a\u0e2d\u0e07; \u0e2a\u0e32\u0e21;\n" +\r
-        "  \u0e2a\u0e35\u0e48; \u0e2b\u0e49\u0e32; \u0e2b\u0e01; \u0e40\u0e08\u0e47\u0e14; \u0e41\u0e1b\u0e14;\n" +\r
-        "  \u0e40\u0e01\u0e49\u0e32; \u0e2a\u0e34\u0e1a; \u0e2a\u0e34\u0e1a\u0e40\u0e2d\u0e47\u0e14;\n" +\r
-        "  \u0e2a\u0e34\u0e1a\u0e2a\u0e2d\u0e07; \u0e2a\u0e34\u0e1a\u0e2a\u0e32\u0e21;\n" +\r
-        "  \u0e2a\u0e34\u0e1a\u0e2a\u0e35\u0e48; \u0e2a\u0e34\u0e1a\u0e2b\u0e49\u0e32;\n" +\r
-        "  \u0e2a\u0e34\u0e1a\u0e2b\u0e01; \u0e2a\u0e34\u0e1a\u0e40\u0e08\u0e47\u0e14;\n" +\r
-        "  \u0e2a\u0e34\u0e1a\u0e41\u0e1b\u0e14; \u0e2a\u0e34\u0e1a\u0e40\u0e01\u0e49\u0e32;\n" +\r
-        "  20: \u0e22\u0e35\u0e48\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +\r
-        "  30: \u0e2a\u0e32\u0e21\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +\r
-        "  40: \u0e2a\u0e35\u0e48\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +\r
-        "  50: \u0e2b\u0e49\u0e32\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +\r
-        "  60: \u0e2b\u0e01\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +\r
-        "  70: \u0e40\u0e08\u0e47\u0e14\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +\r
-        "  80: \u0e41\u0e1b\u0e14\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +\r
-        "  90: \u0e40\u0e01\u0e49\u0e32\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +\r
-        "  100: <<\u0e23\u0e49\u0e2d\u0e22[>>];\n" +\r
-        "  1000: <<\u0e1e\u0e31\u0e19[>>];\n" +\r
-        "  10000: <<\u0e2b\u0e21\u0e37\u0e48\u0e19[>>];\n" +\r
-        "  100000: <<\u0e41\u0e2a\u0e19[>>];\n" +\r
-        "  1,000,000: <<\u0e25\u0e49\u0e32\u0e19[>>];\n" +\r
-        "  1,000,000,000: <<\u0e1e\u0e31\u0e19\u0e25\u0e49\u0e32\u0e19[>>];\n" +\r
-        "  1,000,000,000,000: <<\u0e25\u0e49\u0e32\u0e19\u0e25\u0e49\u0e32\u0e19[>>];\n" +\r
-        "  1,000,000,000,000,000: =#,##0=;\n" +\r
-        "%%alt-ones:\n" +\r
-        "  \u0e28\u0e39\u0e19\u0e22\u0e4c;\n" +\r
-        "  \u0e40\u0e2d\u0e47\u0e14;\n" +\r
-        "  =%default=;\n ; ;; ";\r
-\r
-        RuleBasedNumberFormat formatter\r
-            = new RuleBasedNumberFormat(thaiRules, new Locale("th", "TH", ""));\r
-\r
-        String[][] testData = {\r
-            { "0", "\u0e28\u0e39\u0e19\u0e22\u0e4c" },\r
-            { "1", "\u0e2b\u0e19\u0e36\u0e48\u0e07" },\r
-            { "123.45", "\u0e2b\u0e19\u0e36\u0e48\u0e07\u0e23\u0e49\u0e2d\u0e22\u0e22\u0e35\u0e48\u0e2a\u0e34\u0e1a\u0e2a\u0e32\u0e21\u0e08\u0e38\u0e14\u0e2a\u0e35\u0e48\u0e2b\u0e49\u0e32" }\r
-        };\r
-        \r
-        doTest(formatter, testData, true);\r
-    }\r
-\r
-    public void TestSmallValues() {\r
-    String[][] testData = {\r
-        { "0.001", "zero point zero zero one" },\r
-        { "0.0001", "zero point zero zero zero one" },\r
-        { "0.00001", "zero point zero zero zero zero one" },\r
-        { "0.000001", "zero point zero zero zero zero zero one" },\r
-        { "0.0000001", "zero point zero zero zero zero zero zero one" },\r
-        { "0.00000001", "zero point zero zero zero zero zero zero zero one" },\r
-        { "0.000000001", "zero point zero zero zero zero zero zero zero zero one" },\r
-        { "0.0000000001", "zero point zero zero zero zero zero zero zero zero zero one" },\r
-        { "0.00000000001", "zero point zero zero zero zero zero zero zero zero zero zero one" },\r
-        { "0.000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero one" },\r
-        { "0.0000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero one" },\r
-        { "0.00000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero zero one" },\r
-        { "0.000000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero zero zero one" },\r
-        { "10,000,000.001", "ten million point zero zero one" },\r
-        { "10,000,000.0001", "ten million point zero zero zero one" },\r
-        { "10,000,000.00001", "ten million point zero zero zero zero one" },\r
-        { "10,000,000.000001", "ten million point zero zero zero zero zero one" },\r
-        { "10,000,000.0000001", "ten million point zero zero zero zero zero zero one" },\r
-        { "10,000,000.00000001", "ten million point zero zero zero zero zero zero zero one" },\r
-        { "10,000,000.000000002", "ten million point zero zero zero zero zero zero zero zero two" },\r
-        { "10,000,000", "ten million" },\r
-        { "1,234,567,890.0987654", "one billion two hundred thirty-four million five hundred sixty-seven thousand eight hundred ninety point zero nine eight seven six five four" },\r
-        { "123,456,789.9876543", "one hundred twenty-three million four hundred fifty-six thousand seven hundred eighty-nine point nine eight seven six five four three" },\r
-        { "12,345,678.87654321", "twelve million three hundred forty-five thousand six hundred seventy-eight point eight seven six five four three two one" },\r
-        { "1,234,567.7654321", "one million two hundred thirty-four thousand five hundred sixty-seven point seven six five four three two one" },\r
-        { "123,456.654321", "one hundred twenty-three thousand four hundred fifty-six point six five four three two one" },\r
-        { "12,345.54321", "twelve thousand three hundred forty-five point five four three two one" },\r
-        { "1,234.4321", "one thousand two hundred thirty-four point four three two one" },\r
-        { "123.321", "one hundred twenty-three point three two one" },\r
-        { "0.0000000011754944", "zero point zero zero zero zero zero zero zero zero one one seven five four nine four four" },\r
-        { "0.000001175494351", "zero point zero zero zero zero zero one one seven five four nine four three five one" },\r
-    };\r
-\r
-    RuleBasedNumberFormat formatter\r
-        = new RuleBasedNumberFormat(Locale.US, RuleBasedNumberFormat.SPELLOUT);\r
-    doTest(formatter, testData, true);\r
-    }\r
-\r
-    public void TestRuleSetDisplayName() {\r
-        ULocale.setDefault(ULocale.US);\r
-        String[][] localizations = new String[][] {\r
-            /* public rule sets*/\r
-            {"%simplified", "%default", "%ordinal"},\r
-            /* display names in "en_US" locale*/\r
-            {"en_US", "Simplified", "Default", "Ordinal"},\r
-            /* display names in "zh_Hans" locale*/\r
-            {"zh_Hans", "\u7B80\u5316", "\u7F3A\u7701",  "\u5E8F\u5217"},\r
-            /* display names in a fake locale*/\r
-            {"foo_Bar_BAZ", "Simplified", "Default", "Ordinal"}\r
-        };\r
-        \r
-        //Construct RuleBasedNumberFormat by rule sets and localizations list\r
-        RuleBasedNumberFormat formatter\r
-            = new RuleBasedNumberFormat(ukEnglish, localizations, ULocale.US);\r
-        RuleBasedNumberFormat f2= new RuleBasedNumberFormat(ukEnglish, localizations);\r
-        assertTrue("Check the two formatters' equality", formatter.equals(f2));        \r
-\r
-        //get displayName by name\r
-        String[] ruleSetNames = formatter.getRuleSetNames();\r
-        for (int i=0; i<ruleSetNames.length; i++) {\r
-            logln("Rule set name: " + ruleSetNames[i]);\r
-            String RSName_defLoc = formatter.getRuleSetDisplayName(ruleSetNames[i]);\r
-            assertEquals("Display name in default locale", localizations[1][i+1], RSName_defLoc);\r
-            String RSName_loc = formatter.getRuleSetDisplayName(ruleSetNames[i], ULocale.CHINA);\r
-            assertEquals("Display name in Chinese", localizations[2][i+1], RSName_loc);\r
-        }\r
-                \r
-        // getDefaultRuleSetName\r
-        String defaultRS = formatter.getDefaultRuleSetName();\r
-        //you know that the default rule set is %simplified according to rule sets string ukEnglish\r
-        assertEquals("getDefaultRuleSetName", "%simplified", defaultRS);\r
-        \r
-        //get locales of localizations\r
-        ULocale[] locales = formatter.getRuleSetDisplayNameLocales();\r
-        for (int i=0; i<locales.length; i++) {\r
-            logln(locales[i].getName());\r
-        }\r
-        \r
-        //get displayNames\r
-        String[] RSNames_defLoc = formatter.getRuleSetDisplayNames();\r
-        for (int i=0; i<RSNames_defLoc.length; i++) {\r
-            assertEquals("getRuleSetDisplayNames in default locale", localizations[1][i+1], RSNames_defLoc[i]);\r
-        }\r
-        \r
-        String[] RSNames_loc = formatter.getRuleSetDisplayNames(ULocale.UK);\r
-        for (int i=0; i<RSNames_loc.length; i++) {\r
-            assertEquals("getRuleSetDisplayNames in English", localizations[1][i+1], RSNames_loc[i]);\r
-        }    \r
-        \r
-        RSNames_loc = formatter.getRuleSetDisplayNames(ULocale.CHINA);\r
-        for (int i=0; i<RSNames_loc.length; i++) {\r
-            assertEquals("getRuleSetDisplayNames in Chinese", localizations[2][i+1], RSNames_loc[i]);\r
-        }        \r
-\r
-        RSNames_loc = formatter.getRuleSetDisplayNames(new ULocale("foo_Bar_BAZ"));\r
-        for (int i=0; i<RSNames_loc.length; i++) {\r
-            assertEquals("getRuleSetDisplayNames in fake locale", localizations[3][i+1], RSNames_loc[i]);\r
-        }              \r
-    }\r
-\r
-    public void TestAllLocales() {\r
-        StringBuffer errors = null;\r
-        ULocale[] locales = ULocale.getAvailableLocales();\r
-        String[] names = {\r
-            " (spellout) ",\r
-            " (ordinal)  ",\r
-            " (duration) "\r
-        };\r
-        double[] numbers = {45.678, 1, 2, 10, 11, 100, 110, 200, 1000, 1111, -1111};\r
-        Random r = null;\r
-\r
-        // RBNF parse is extremely slow when lenient option is enabled.\r
-        // For non-exhaustive mode, we only test a few locales.\r
-        // "nl_NL", "be" had crash problem reported by #6534\r
-        String[] parseLocales = {"en_US", "nl_NL", "be"};\r
-\r
-        for (int i = 0; i < locales.length; ++i) {\r
-            ULocale loc = locales[i];\r
-            int count = numbers.length;\r
-            boolean testParse = true;\r
-            if (getInclusion() <= 5) {\r
-                testParse = false;\r
-                for (int k = 0; k < parseLocales.length; k++) {\r
-                    if (loc.toString().equals(parseLocales[k])) {\r
-                        testParse = true;\r
-                        break;\r
-                    }\r
-                }\r
-            } else {\r
-                //RBNF parse is too slow.  Increase count only for debugging purpose for now.\r
-                //count = 100;\r
-            }\r
-\r
-            for (int j = 0; j < 3; ++j) {\r
-                RuleBasedNumberFormat fmt = new RuleBasedNumberFormat(loc, j+1);\r
-\r
-                for (int c = 0; c < count; c++) {\r
-                    double n;\r
-                    if (c < numbers.length) {\r
-                        n = numbers[c];\r
-                    } else {\r
-                        if (r == null) {\r
-                            r = createRandom();\r
-                        }\r
-                        n = ((int)(r.nextInt(10000) - 3000)) / 16d;\r
-                    }\r
-\r
-                    String s = fmt.format(n);\r
-                    logln(loc.getName() + names[j] + "success format: " + n + " -> " + s);\r
-\r
-                    if (testParse) {\r
-                        // We do not validate the result in this test case,\r
-                        // because there are cases which do not round trip by design.\r
-                        try {\r
-                            // non-lenient parse\r
-                            fmt.setLenientParseMode(false);\r
-                            Number num = fmt.parse(s);\r
-                            logln(loc.getName() + names[j] + "success parse: " + s + " -> " + num);\r
-\r
-                            // lenient parse\r
-                            fmt.setLenientParseMode(true);\r
-                            num = fmt.parse(s);\r
-                            logln(loc.getName() + names[j] + "success parse (lenient): " + s + " -> " + num);\r
-                        } catch (ParseException pe) {\r
-                            String msg = loc.getName() + names[j] + "ERROR:" + pe.getMessage();\r
-                            logln(msg);\r
-                            if (errors == null) {\r
-                                errors = new StringBuffer();\r
-                            }\r
-                            errors.append("\n" + msg);\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        if (errors != null) {\r
-            //TODO: We need to fix parse problems - see #6895 / #6896\r
-            //errln(errors.toString());\r
-            logln(errors.toString());\r
-        }\r
-    }\r
-\r
-    void doTest(RuleBasedNumberFormat formatter, String[][] testData,\r
-                boolean testParsing) {\r
-    //        NumberFormat decFmt = NumberFormat.getInstance(Locale.US);\r
-    NumberFormat decFmt = new DecimalFormat("#,###.################");\r
-        try {\r
-            for (int i = 0; i < testData.length; i++) {\r
-                String number = testData[i][0];\r
-                String expectedWords = testData[i][1];\r
-                logln("test[" + i + "] number: " + number + " target: " + expectedWords);\r
-                Number num = decFmt.parse(number);\r
-                String actualWords = formatter.format(num);\r
-\r
-                if (!actualWords.equals(expectedWords)) {\r
-                    errln("Spot check format failed: for " + number + ", expected\n    "\r
-                          + expectedWords + ", but got\n    " +\r
-                          actualWords);\r
-                }\r
-                else if (testParsing) {\r
-                    String actualNumber = decFmt.format(formatter\r
-                                                        .parse(actualWords));\r
-\r
-                    if (!actualNumber.equals(number)) {\r
-                        errln("Spot check parse failed: for " + actualWords +\r
-                              ", expected " + number + ", but got " +\r
-                              actualNumber);\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        catch (Throwable e) {\r
-            e.printStackTrace();\r
-            errln("Test failed with exception: " + e.toString());\r
-        }\r
-    }\r
-\r
-    void doLenientParseTest(RuleBasedNumberFormat formatter,\r
-                            String[][] testData) {\r
-        NumberFormat decFmt = NumberFormat.getInstance(Locale.US);\r
-\r
-        try {\r
-            for (int i = 0; i < testData.length; i++) {\r
-                String words = testData[i][0];\r
-                String expectedNumber = testData[i][1];\r
-                String actualNumber = decFmt.format(formatter.parse(words));\r
-\r
-                if (!actualNumber.equals(expectedNumber)) {\r
-                    errln("Lenient-parse spot check failed: for "\r
-                          + words + ", expected " + expectedNumber\r
-                          + ", but got " + actualNumber);\r
-                }\r
-            }\r
-        }\r
-        catch (Throwable e) {\r
-            errln("Test failed with exception: " + e.toString());\r
-            e.printStackTrace();\r
-        }\r
-    }\r
-\r
-\r
-    /**\r
-     * Spellout rules for U.K. English.  \r
-     * I borrow the rule sets for TestRuleSetDisplayName()\r
-     */\r
-    public static final String ukEnglish =\r
-        "%simplified:\n"\r
-        + "    -x: minus >>;\n"\r
-        + "    x.x: << point >>;\n"\r
-        + "    zero; one; two; three; four; five; six; seven; eight; nine;\n"\r
-        + "    ten; eleven; twelve; thirteen; fourteen; fifteen; sixteen;\n"\r
-        + "        seventeen; eighteen; nineteen;\n"\r
-        + "    20: twenty[->>];\n"\r
-        + "    30: thirty[->>];\n"\r
-        + "    40: forty[->>];\n"\r
-        + "    50: fifty[->>];\n"\r
-        + "    60: sixty[->>];\n"\r
-        + "    70: seventy[->>];\n"\r
-        + "    80: eighty[->>];\n"\r
-        + "    90: ninety[->>];\n"\r
-        + "    100: << hundred[ >>];\n"\r
-        + "    1000: << thousand[ >>];\n"\r
-        + "    1,000,000: << million[ >>];\n"\r
-        + "    1,000,000,000,000: << billion[ >>];\n"\r
-        + "    1,000,000,000,000,000: =#,##0=;\n"\r
-        + "%alt-teens:\n"\r
-        + "    =%simplified=;\n"\r
-        + "    1000>: <%%alt-hundreds<[ >>];\n"\r
-        + "    10,000: =%simplified=;\n"\r
-        + "    1,000,000: << million[ >%simplified>];\n"\r
-        + "    1,000,000,000,000: << billion[ >%simplified>];\n"\r
-        + "    1,000,000,000,000,000: =#,##0=;\n"\r
-        + "%%alt-hundreds:\n"\r
-        + "    0: SHOULD NEVER GET HERE!;\n"\r
-        + "    10: <%simplified< thousand;\n"\r
-        + "    11: =%simplified= hundred>%%empty>;\n"\r
-        + "%%empty:\n"\r
-        + "    0:;"\r
-        + "%ordinal:\n"\r
-        + "    zeroth; first; second; third; fourth; fifth; sixth; seventh;\n"\r
-        + "        eighth; ninth;\n"\r
-        + "    tenth; eleventh; twelfth; thirteenth; fourteenth;\n"\r
-        + "        fifteenth; sixteenth; seventeenth; eighteenth;\n"\r
-        + "        nineteenth;\n"\r
-        + "    twentieth; twenty->>;\n"\r
-        + "    30: thirtieth; thirty->>;\n"\r
-        + "    40: fortieth; forty->>;\n"\r
-        + "    50: fiftieth; fifty->>;\n"\r
-        + "    60: sixtieth; sixty->>;\n"\r
-        + "    70: seventieth; seventy->>;\n"\r
-        + "    80: eightieth; eighty->>;\n"\r
-        + "    90: ninetieth; ninety->>;\n"\r
-        + "    100: <%simplified< hundredth; <%simplified< hundred >>;\n"\r
-        + "    1000: <%simplified< thousandth; <%simplified< thousand >>;\n"\r
-        + "    1,000,000: <%simplified< millionth; <%simplified< million >>;\n"\r
-        + "    1,000,000,000,000: <%simplified< billionth;\n"\r
-        + "        <%simplified< billion >>;\n"\r
-        + "    1,000,000,000,000,000: =#,##0=;"\r
-        + "%default:\n"\r
-        + "    -x: minus >>;\n"\r
-        + "    x.x: << point >>;\n"\r
-        + "    =%simplified=;\n"\r
-        + "    100: << hundred[ >%%and>];\n"\r
-        + "    1000: << thousand[ >%%and>];\n"\r
-        + "    100,000>>: << thousand[>%%commas>];\n"\r
-        + "    1,000,000: << million[>%%commas>];\n"\r
-        + "    1,000,000,000,000: << billion[>%%commas>];\n"\r
-        + "    1,000,000,000,000,000: =#,##0=;\n"\r
-        + "%%and:\n"\r
-        + "    and =%default=;\n"\r
-        + "    100: =%default=;\n"\r
-        + "%%commas:\n"\r
-        + "    ' and =%default=;\n"\r
-        + "    100: , =%default=;\n"\r
-        + "    1000: , <%default< thousand, >%default>;\n"\r
-        + "    1,000,000: , =%default=;"\r
-        + "%%lenient-parse:\n"\r
-        + "    & ' ' , ',' ;\n";\r
-\r
-}\r
-\r
+//##header J2SE15
+/*
+ *******************************************************************************
+ * Copyright (C) 1996-2009, International Business Machines Corporation and    *
+ * others. All Rights Reserved.                                                *
+ *******************************************************************************
+ */
+package com.ibm.icu.dev.test.format;
+
+import java.math.BigInteger;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.util.Locale;
+import java.util.Random;
+
+import com.ibm.icu.dev.test.TestFmwk;
+import com.ibm.icu.text.RuleBasedNumberFormat;
+import com.ibm.icu.util.ULocale;
+
+public class RbnfTest extends TestFmwk {
+    public static void main(String[] args) {
+        RbnfTest test = new RbnfTest();
+
+        try {
+            test.run(args);
+        }
+        catch (Throwable e) {
+            System.out.println("Entire test failed because of exception: "
+                               + e.toString());
+            e.printStackTrace();
+        }
+    }
+
+    static String fracRules = 
+        "%main:\n" +
+        // this rule formats the number if it's 1 or more.  It formats
+        // the integral part using a DecimalFormat ("#,##0" puts
+        // thousands separators in the right places) and the fractional
+        // part using %%frac.  If there is no fractional part, it
+        // just shows the integral part.
+        "    x.0: <#,##0<[ >%%frac>];\n" +
+        // this rule formats the number if it's between 0 and 1.  It
+        // shows only the fractional part (0.5 shows up as "1/2," not
+        // "0 1/2")
+        "    0.x: >%%frac>;\n" +
+        // the fraction rule set.  This works the same way as the one in the
+        // preceding example: We multiply the fractional part of the number
+        // being formatted by each rule's base value and use the rule that
+        // produces the result closest to 0 (or the first rule that produces 0).
+        // Since we only provide rules for the numbers from 2 to 10, we know
+        // we'll get a fraction with a denominator between 2 and 10.
+        // "<0<" causes the numerator of the fraction to be formatted
+        // using numerals
+        "%%frac:\n" +
+        "    2: 1/2;\n" +
+        "    3: <0</3;\n" +
+        "    4: <0</4;\n" +
+        "    5: <0</5;\n" +
+        "    6: <0</6;\n" +
+        "    7: <0</7;\n" +
+        "    8: <0</8;\n" +
+        "    9: <0</9;\n" +
+        "   10: <0</10;\n";
+
+    static {
+        // mondo hack
+    char[] fracRulesArr = fracRules.toCharArray();
+        int len = fracRulesArr.length;
+        int change = 2;
+        for (int i = 0; i < len; ++i) {
+            char ch = fracRulesArr[i];
+            if (ch == '\n') {
+                change = 2; // change ok
+            } else if (ch == ':') {
+                change = 1; // change, but once we hit a non-space char, don't change
+            } else if (ch == ' ') {
+                if (change != 0) {
+                    fracRulesArr[i] = (char)0x200e;
+                }
+            } else {
+                if (change == 1) {
+                    change = 0;
+                }
+            }
+        }
+    fracRules = new String(fracRulesArr);
+    }
+
+    static final String durationInSecondsRules =
+        // main rule set for formatting with words
+        "%with-words:\n"
+        // take care of singular and plural forms of "second"
+        + "    0 seconds; 1 second; =0= seconds;\n"
+        // use %%min to format values greater than 60 seconds
+        + "    60/60: <%%min<[, >>];\n"
+        // use %%hr to format values greater than 3,600 seconds
+        // (the ">>>" below causes us to see the number of minutes
+        // when when there are zero minutes)
+        + "    3600/60: <%%hr<[, >>>];\n"
+        // this rule set takes care of the singular and plural forms
+        // of "minute"
+        + "%%min:\n"
+        + "    0 minutes; 1 minute; =0= minutes;\n"
+        // this rule set takes care of the singular and plural forms
+        // of "hour"
+        + "%%hr:\n"
+        + "    0 hours; 1 hour; =0= hours;\n"
+
+        // main rule set for formatting in numerals
+        + "%in-numerals:\n"
+        // values below 60 seconds are shown with "sec."
+        + "    =0= sec.;\n"
+        // higher values are shown with colons: %%min-sec is used for
+        // values below 3,600 seconds...
+        + "    60: =%%min-sec=;\n"
+        // ...and %%hr-min-sec is used for values of 3,600 seconds
+        // and above
+        + "    3600: =%%hr-min-sec=;\n"
+        // this rule causes values of less than 10 minutes to show without
+        // a leading zero
+        + "%%min-sec:\n"
+        + "    0: :=00=;\n"
+        + "    60/60: <0<>>;\n"
+        // this rule set is used for values of 3,600 or more.  Minutes are always
+        // shown, and always shown with two digits
+        + "%%hr-min-sec:\n"
+        + "    0: :=00=;\n"
+        + "    60/60: <00<>>;\n"
+        + "    3600/60: <#,##0<:>>>;\n"
+        // the lenient-parse rules allow several different characters to be used
+        // as delimiters between hours, minutes, and seconds
+        + "%%lenient-parse:\n"
+        + "    & : = . = ' ' = -;\n";
+
+    public void TestCoverage() {
+        // extra calls to boost coverage numbers
+        RuleBasedNumberFormat fmt0 = new RuleBasedNumberFormat(RuleBasedNumberFormat.SPELLOUT);
+        RuleBasedNumberFormat fmt1 = (RuleBasedNumberFormat)fmt0.clone();
+        RuleBasedNumberFormat fmt2 = new RuleBasedNumberFormat(RuleBasedNumberFormat.SPELLOUT);
+        if (!fmt0.equals(fmt0)) {
+            errln("self equality fails");
+        }
+        if (!fmt0.equals(fmt1)) {
+            errln("clone equality fails");
+        }
+        if (!fmt0.equals(fmt2)) {
+            errln("duplicate equality fails");
+        }
+        String str = fmt0.toString();
+        logln(str);
+
+        RuleBasedNumberFormat fmt3 =  new RuleBasedNumberFormat(durationInSecondsRules);
+
+        if (fmt0.equals(fmt3)) {
+            errln("nonequal fails");
+        }
+        if (!fmt3.equals(fmt3)) {
+            errln("self equal 2 fails");
+        }
+        str = fmt3.toString();
+        logln(str);
+
+        String[] names = fmt3.getRuleSetNames();
+
+        try {
+            fmt3.setDefaultRuleSet(null);
+            fmt3.setDefaultRuleSet("%%foo");
+            errln("sdrf %%foo didn't fail");
+        }
+        catch (Exception e) {
+            logln("Got the expected exception");
+        }
+
+        try {
+            fmt3.setDefaultRuleSet("%bogus");
+            errln("sdrf %bogus didn't fail");
+        }
+        catch (Exception e) {
+            logln("Got the expected exception");
+        }
+
+        try {
+            str = fmt3.format(2.3, names[0]);
+            logln(str);
+            str = fmt3.format(2.3, "%%foo");
+            errln("format double %%foo didn't fail");
+        }
+        catch (Exception e) {
+            logln("Got the expected exception");
+        }
+
+        try {
+            str = fmt3.format(123L, names[0]);
+            logln(str);
+            str = fmt3.format(123L, "%%foo");
+            errln("format double %%foo didn't fail");
+        }
+        catch (Exception e) {
+            logln("Got the expected exception");
+        }
+
+        RuleBasedNumberFormat fmt4 = new RuleBasedNumberFormat(fracRules, Locale.ENGLISH);
+        RuleBasedNumberFormat fmt5 = new RuleBasedNumberFormat(fracRules, Locale.ENGLISH);
+        str = fmt4.toString();
+        logln(str);
+        if (!fmt4.equals(fmt5)) {
+            errln("duplicate 2 equality failed");
+        }
+        str = fmt4.format(123L);
+        logln(str);
+        try {
+            Number num = fmt4.parse(str);
+            logln(num.toString());
+        }
+        catch (Exception e) {
+            errln("parse caught exception");
+        }
+
+        str = fmt4.format(.000123);
+        logln(str);
+        try {
+            Number num = fmt4.parse(str);
+            logln(num.toString());
+        }
+        catch (Exception e) {
+            errln("parse caught exception");
+        }
+
+        str = fmt4.format(456.000123);
+        logln(str);
+        try {
+            Number num = fmt4.parse(str);
+            logln(num.toString());
+        }
+        catch (Exception e) {
+            errln("parse caught exception");
+        }
+    }
+
+    public void TestUndefinedSpellout() {
+        Locale greek = new Locale("el", "", "");
+        RuleBasedNumberFormat[] formatters = {
+            new RuleBasedNumberFormat(greek, RuleBasedNumberFormat.SPELLOUT),
+            new RuleBasedNumberFormat(greek, RuleBasedNumberFormat.ORDINAL),
+            new RuleBasedNumberFormat(greek, RuleBasedNumberFormat.DURATION),
+        };
+
+        String[] data = {
+            "0",
+            "1",
+            "15",
+            "20",
+            "23",
+            "73",
+            "88",
+            "100",
+            "106",
+            "127",
+            "200",
+            "579",
+            "1,000",
+            "2,000",
+            "3,004",
+            "4,567",
+            "15,943",
+            "105,000",
+            "2,345,678",
+            "-36",
+            "-36.91215",
+            "234.56789"
+        };
+
+        NumberFormat decFormat = NumberFormat.getInstance(Locale.US);
+        for (int j = 0; j < formatters.length; ++j) {
+            com.ibm.icu.text.NumberFormat formatter = formatters[j];
+            logln("formatter[" + j + "]");
+            for (int i = 0; i < data.length; ++i) {
+                try {
+                    String result = formatter.format(decFormat.parse(data[i]));
+                    logln("[" + i + "] " + data[i] + " ==> " + result);
+                }
+                catch (Exception e) {
+                    errln("formatter[" + j + "], data[" + i + "] " + data[i] + " threw exception " + e.getMessage());
+                }
+            }
+        }
+    }
+
+    /**
+     * Perform a simple spot check on the English spellout rules
+     */
+    public void TestEnglishSpellout() {
+        RuleBasedNumberFormat formatter
+            = new RuleBasedNumberFormat(Locale.US,
+                                        RuleBasedNumberFormat.SPELLOUT);
+        String[][] testData = {
+            { "1", "one" },
+            { "15", "fifteen" },
+            { "20", "twenty" },
+            { "23", "twenty-three" },
+            { "73", "seventy-three" },
+            { "88", "eighty-eight" },
+            { "100", "one hundred" },
+            { "106", "one hundred six" },
+            { "127", "one hundred twenty-seven" },
+            { "200", "two hundred" },
+            { "579", "five hundred seventy-nine" },
+            { "1,000", "one thousand" },
+            { "2,000", "two thousand" },
+            { "3,004", "three thousand four" },
+            { "4,567", "four thousand five hundred sixty-seven" },
+            { "15,943", "fifteen thousand nine hundred forty-three" },
+            { "2,345,678", "two million three hundred forty-five "
+              + "thousand six hundred seventy-eight" },
+            { "-36", "minus thirty-six" },
+            { "234.567", "two hundred thirty-four point five six seven" }
+        };
+
+        doTest(formatter, testData, true);
+
+        formatter.setLenientParseMode(true);
+        String[][] lpTestData = {
+            { "FOurhundred     thiRTY six", "436" },
+            // test spaces before fifty-7 causing lenient parse match of "fifty-" to " fifty"
+            // leaving "-7" for remaining parse, resulting in 2643 as the parse result.
+            { "fifty-7", "57" },
+            { " fifty-7", "57" },
+            { "  fifty-7", "57" },
+            { "2 thousand six HUNDRED   fifty-7", "2,657" },
+            { "fifteen hundred and zero", "1,500" }
+        };
+        doLenientParseTest(formatter, lpTestData);
+    }
+
+    /**
+     * Perform a simple spot check on the English ordinal-abbreviation rules
+     */
+    public void TestOrdinalAbbreviations() {
+        RuleBasedNumberFormat formatter
+            = new RuleBasedNumberFormat(Locale.US,
+                                        RuleBasedNumberFormat.ORDINAL);
+        String[][] testData = {
+            { "1", "1\u02e2\u1d57" },
+            { "2", "2\u207f\u1d48" },
+            { "3", "3\u02b3\u1d48" },
+            { "4", "4\u1d57\u02b0" },
+            { "7", "7\u1d57\u02b0" },
+            { "10", "10\u1d57\u02b0" },
+            { "11", "11\u1d57\u02b0" },
+            { "13", "13\u1d57\u02b0" },
+            { "20", "20\u1d57\u02b0" },
+            { "21", "21\u02e2\u1d57" },
+            { "22", "22\u207f\u1d48" },
+            { "23", "23\u02b3\u1d48" },
+            { "24", "24\u1d57\u02b0" },
+            { "33", "33\u02b3\u1d48" },
+            { "102", "102\u207f\u1d48" },
+            { "312", "312\u1d57\u02b0" },
+            { "12,345", "12,345\u1d57\u02b0" }
+        };
+
+        doTest(formatter, testData, false);
+    }
+
+    /**
+     * Perform a simple spot check on the duration-formatting rules
+     */
+    public void TestDurations() {
+        RuleBasedNumberFormat formatter
+            = new RuleBasedNumberFormat(Locale.US,
+                                        RuleBasedNumberFormat.DURATION);
+        String[][] testData = {
+            { "3,600", "1:00:00" },             //move me and I fail
+            { "0", "0 sec." },
+            { "1", "1 sec." },
+            { "24", "24 sec." },
+            { "60", "1:00" },
+            { "73", "1:13" },
+            { "145", "2:25" },
+            { "666", "11:06" },
+            //            { "3,600", "1:00:00" },
+            { "3,740", "1:02:20" },
+            { "10,293", "2:51:33" }
+        };
+
+        doTest(formatter, testData, true);
+
+        formatter.setLenientParseMode(true);
+        String[][] lpTestData = {
+            { "2-51-33", "10,293" }
+        };
+        doLenientParseTest(formatter, lpTestData);
+    }
+
+    /**
+     * Perform a simple spot check on the Spanish spellout rules
+     */
+    public void TestSpanishSpellout() {
+        RuleBasedNumberFormat formatter
+            = new RuleBasedNumberFormat(new Locale("es", "es",
+                                                   ""), RuleBasedNumberFormat.SPELLOUT);
+        String[][] testData = {
+            { "1", "uno" },
+            { "6", "seis" },
+            { "16", "diecis\u00e9is" },
+            { "20", "veinte" },
+            { "24", "veinticuatro" },
+            { "26", "veintis\u00e9is" },
+            { "73", "setenta y tres" },
+            { "88", "ochenta y ocho" },
+            { "100", "cien" },
+            { "106", "ciento seis" },
+            { "127", "ciento veintisiete" },
+            { "200", "doscientos" },
+            { "579", "quinientos setenta y nueve" },
+            { "1,000", "mil" },
+            { "2,000", "dos mil" },
+            { "3,004", "tres mil cuatro" },
+            { "4,567", "cuatro mil quinientos sesenta y siete" },
+            { "15,943", "quince mil novecientos cuarenta y tres" },
+            { "2,345,678", "dos millones trescientos cuarenta y cinco mil "
+              + "seiscientos setenta y ocho"},
+            { "-36", "menos treinta y seis" },
+            { "234.567", "doscientos treinta y cuatro coma cinco seis siete" }
+        };
+
+        doTest(formatter, testData, true);
+    }
+
+    /**
+     * Perform a simple spot check on the French spellout rules
+     */
+    public void TestFrenchSpellout() {
+        RuleBasedNumberFormat formatter
+            = new RuleBasedNumberFormat(Locale.FRANCE,
+                                        RuleBasedNumberFormat.SPELLOUT);
+        String[][] testData = {
+            { "1", "un" },
+            { "15", "quinze" },
+            { "20", "vingt" },
+            { "21", "vingt-et-un" },
+            { "23", "vingt-trois" },
+            { "62", "soixante-deux" },
+            { "70", "soixante-dix" },
+            { "71", "soixante-et-onze" },
+            { "73", "soixante-treize" },
+            { "80", "quatre-vingts" },
+            { "88", "quatre-vingt-huit" },
+            { "100", "cent" },
+            { "106", "cent-six" },
+            { "127", "cent-vingt-sept" },
+            { "200", "deux-cents" },
+            { "579", "cinq-cent-soixante-dix-neuf" },
+            { "1,000", "mille" },
+            { "1,123", "mille-cent-vingt-trois" },
+            { "1,594", "mille-cinq-cent-quatre-vingt-quatorze" },
+            { "2,000", "deux-mille" },
+            { "3,004", "trois-mille-quatre" },
+            { "4,567", "quatre-mille-cinq-cent-soixante-sept" },
+            { "15,943", "quinze-mille-neuf-cent-quarante-trois" },
+            { "2,345,678", "deux millions trois-cent-quarante-cinq-mille-"
+              + "six-cent-soixante-dix-huit" },
+            { "-36", "moins trente-six" },
+            { "234.567", "deux-cent-trente-quatre virgule cinq six sept" }
+        };
+
+        doTest(formatter, testData, true);
+
+        formatter.setLenientParseMode(true);
+        String[][] lpTestData = {
+            { "trente-et-un", "31" },
+            { "un cent quatre vingt dix huit", "198" }
+        };
+        doLenientParseTest(formatter, lpTestData);
+    }
+
+    /**
+     * Perform a simple spot check on the Swiss French spellout rules
+     */
+    public void TestSwissFrenchSpellout() {
+        RuleBasedNumberFormat formatter
+            = new RuleBasedNumberFormat(new Locale("fr", "CH",
+                                                   ""), RuleBasedNumberFormat.SPELLOUT);
+        String[][] testData = {
+            { "1", "un" },
+            { "15", "quinze" },
+            { "20", "vingt" },
+            { "21", "vingt-et-un" },
+            { "23", "vingt-trois" },
+            { "62", "soixante-deux" },
+            { "70", "septante" },
+            { "71", "septante-et-un" },
+            { "73", "septante-trois" },
+            { "80", "huitante" },
+            { "88", "huitante-huit" },
+            { "100", "cent" },
+            { "106", "cent-six" },
+            { "127", "cent-vingt-sept" },
+            { "200", "deux-cents" },
+            { "579", "cinq-cent-septante-neuf" },
+            { "1,000", "mille" },
+            { "1,123", "mille-cent-vingt-trois" },
+            { "1,594", "mille-cinq-cent-nonante-quatre" },
+            { "2,000", "deux-mille" },
+            { "3,004", "trois-mille-quatre" },
+            { "4,567", "quatre-mille-cinq-cent-soixante-sept" },
+            { "15,943", "quinze-mille-neuf-cent-quarante-trois" },
+            { "2,345,678", "deux millions trois-cent-quarante-cinq-mille-"
+              + "six-cent-septante-huit" },
+            { "-36", "moins trente-six" },
+            { "234.567", "deux-cent-trente-quatre virgule cinq six sept" }
+        };
+
+        doTest(formatter, testData, true);
+    }
+
+    /**
+     * Perform a simple spot check on the Italian spellout rules
+     */
+    public void TestItalianSpellout() {
+        RuleBasedNumberFormat formatter
+            = new RuleBasedNumberFormat(Locale.ITALIAN,
+                                        RuleBasedNumberFormat.SPELLOUT);
+        String[][] testData = {
+            { "1", "uno" },
+            { "15", "quindici" },
+            { "20", "venti" },
+            { "23", "venti\u00ADtr\u00E9" },
+            { "73", "settanta\u00ADtr\u00E9" },
+            { "88", "ottant\u00ADotto" },
+            { "100", "cento" },
+            { "106", "cento\u00ADsei" },
+            { "108", "cent\u00ADotto" },
+            { "127", "cento\u00ADventi\u00ADsette" },
+            { "181", "cent\u00ADottant\u00ADuno" },
+            { "200", "due\u00ADcento" },
+            { "579", "cinque\u00ADcento\u00ADsettanta\u00ADnove" },
+            { "1,000", "mille" },
+            { "2,000", "due\u00ADmila" },
+            { "3,004", "tre\u00ADmila\u00ADquattro" },
+            { "4,567", "quattro\u00ADmila\u00ADcinque\u00ADcento\u00ADsessanta\u00ADsette" },
+            { "15,943", "quindici\u00ADmila\u00ADnove\u00ADcento\u00ADquaranta\u00ADtr\u00E9" },
+            { "-36", "meno trenta\u00ADsei" },
+            { "234.567", "due\u00ADcento\u00ADtrenta\u00ADquattro virgola cinque sei sette" }
+        };
+
+        doTest(formatter, testData, true);
+    }
+
+    /**
+     * Perform a simple spot check on the German spellout rules
+     */
+    public void TestGermanSpellout() {
+        RuleBasedNumberFormat formatter
+            = new RuleBasedNumberFormat(Locale.GERMANY,
+                                        RuleBasedNumberFormat.SPELLOUT);
+        String[][] testData = {
+            { "1", "eins" },
+            { "15", "f\u00fcnfzehn" },
+            { "20", "zwanzig" },
+            { "23", "drei\u00ADund\u00ADzwanzig" },
+            { "73", "drei\u00ADund\u00ADsiebzig" },
+            { "88", "acht\u00ADund\u00ADachtzig" },
+            { "100", "ein\u00ADhundert" },
+            { "106", "ein\u00ADhundert\u00ADsechs" },
+            { "127", "ein\u00ADhundert\u00ADsieben\u00ADund\u00ADzwanzig" },
+            { "200", "zwei\u00ADhundert" },
+            { "579", "f\u00fcnf\u00ADhundert\u00ADneun\u00ADund\u00ADsiebzig" },
+            { "1,000", "ein\u00ADtausend" },
+            { "2,000", "zwei\u00ADtausend" },
+            { "3,004", "drei\u00ADtausend\u00ADvier" },
+            { "4,567", "vier\u00ADtausend\u00ADf\u00fcnf\u00ADhundert\u00ADsieben\u00ADund\u00ADsechzig" },
+            { "15,943", "f\u00fcnfzehn\u00ADtausend\u00ADneun\u00ADhundert\u00ADdrei\u00ADund\u00ADvierzig" },
+            { "2,345,678", "zwei Millionen drei\u00ADhundert\u00ADf\u00fcnf\u00ADund\u00ADvierzig\u00ADtausend\u00AD"
+              + "sechs\u00ADhundert\u00ADacht\u00ADund\u00ADsiebzig" }
+        };
+
+        doTest(formatter, testData, true);
+
+        formatter.setLenientParseMode(true);
+        String[][] lpTestData = {
+            { "ein Tausend sechs Hundert fuenfunddreissig", "1,635" }
+        };
+        doLenientParseTest(formatter, lpTestData);
+    }
+
+    /**
+     * Perform a simple spot check on the Thai spellout rules
+     */
+    public void TestThaiSpellout() {
+        RuleBasedNumberFormat formatter
+            = new RuleBasedNumberFormat(new Locale("th", "TH", ""),
+                                        RuleBasedNumberFormat.SPELLOUT);
+        String[][] testData = {
+            { "0", "\u0e28\u0e39\u0e19\u0e22\u0e4c" },
+            { "1", "\u0e2b\u0e19\u0e36\u0e48\u0e07" },
+            { "10", "\u0e2a\u0e34\u0e1a" },
+            { "11", "\u0e2a\u0e34\u0e1a\u200b\u0e40\u0e2d\u0e47\u0e14" },
+            { "21", "\u0e22\u0e35\u0e48\u200b\u0e2a\u0e34\u0e1a\u200b\u0e40\u0e2d\u0e47\u0e14" },
+            { "101", "\u0e2b\u0e19\u0e36\u0e48\u0e07\u200b\u0e23\u0e49\u0e2d\u0e22\u200b\u0e2b\u0e19\u0e36\u0e48\u0e07" },
+            { "1.234", "\u0e2b\u0e19\u0e36\u0e48\u0e07\u200b\u0e08\u0e38\u0e14\u200b\u0e2a\u0e2d\u0e07\u0e2a\u0e32\u0e21\u0e2a\u0e35\u0e48" },
+            { "21.45", "\u0e22\u0e35\u0e48\u200b\u0e2a\u0e34\u0e1a\u200b\u0e40\u0e2d\u0e47\u0e14\u200b\u0e08\u0e38\u0e14\u200b\u0e2a\u0e35\u0e48\u0e2b\u0e49\u0e32" },
+            { "22.45", "\u0e22\u0e35\u0e48\u200b\u0e2a\u0e34\u0e1a\u200b\u0e2a\u0e2d\u0e07\u200b\u0e08\u0e38\u0e14\u200b\u0e2a\u0e35\u0e48\u0e2b\u0e49\u0e32" },
+            { "23.45", "\u0e22\u0e35\u0e48\u200b\u0e2a\u0e34\u0e1a\u200b\u0e2a\u0e32\u0e21\u200b\u0e08\u0e38\u0e14\u200b\u0e2a\u0e35\u0e48\u0e2b\u0e49\u0e32" },
+            { "123.45", "\u0e2b\u0e19\u0e36\u0e48\u0e07\u200b\u0e23\u0e49\u0e2d\u0e22\u200b\u0e22\u0e35\u0e48\u200b\u0e2a\u0e34\u0e1a\u200b\u0e2a\u0e32\u0e21\u200b\u0e08\u0e38\u0e14\u200b\u0e2a\u0e35\u0e48\u0e2b\u0e49\u0e32" },
+            { "12,345.678", "\u0E2B\u0E19\u0E36\u0E48\u0E07\u200b\u0E2B\u0E21\u0E37\u0E48\u0E19\u200b\u0E2A\u0E2D\u0E07\u200b\u0E1E\u0E31\u0E19\u200b\u0E2A\u0E32\u0E21\u200b\u0E23\u0E49\u0E2D\u0E22\u200b\u0E2A\u0E35\u0E48\u200b\u0E2A\u0E34\u0E1A\u200b\u0E2B\u0E49\u0E32\u200b\u0E08\u0E38\u0E14\u200b\u0E2B\u0E01\u0E40\u0E08\u0E47\u0E14\u0E41\u0E1B\u0E14" },
+        };
+
+        doTest(formatter, testData, true);
+
+        /*
+          formatter.setLenientParseMode(true);
+          String[][] lpTestData = {
+          { "ein Tausend sechs Hundert fuenfunddreissig", "1,635" }
+          };
+          doLenientParseTest(formatter, lpTestData);
+        */
+    }
+
+    public void TestFractionalRuleSet() {
+
+
+        RuleBasedNumberFormat formatter =
+            new RuleBasedNumberFormat(fracRules, Locale.ENGLISH);
+
+        String[][] testData = {
+            { "0", "0" },
+            { "1", "1" },
+            { "10", "10" },
+            { ".1", "1/10" },
+            { ".11", "1/9" },
+            { ".125", "1/8" },
+            { ".1428", "1/7" },
+            { ".1667", "1/6" },
+            { ".2", "1/5" },
+            { ".25", "1/4" },
+            { ".333", "1/3" },
+            { ".5", "1/2" },
+            { "1.1", "1 1/10" },
+            { "2.11", "2 1/9" },
+            { "3.125", "3 1/8" },
+            { "4.1428", "4 1/7" },
+            { "5.1667", "5 1/6" },
+            { "6.2", "6 1/5" },
+            { "7.25", "7 1/4" },
+            { "8.333", "8 1/3" },
+            { "9.5", "9 1/2" },
+            { ".2222", "2/9" },
+            { ".4444", "4/9" },
+            { ".5555", "5/9" },
+            { "1.2856", "1 2/7" }
+        };
+        doTest(formatter, testData, false); // exact values aren't parsable from fractions
+    }
+
+    public void TestSwedishSpellout()
+    {
+        Locale locale = new Locale("sv", "", "");
+        RuleBasedNumberFormat formatter = new RuleBasedNumberFormat(locale, RuleBasedNumberFormat.SPELLOUT);
+
+        String[][] testDataDefault = {
+            { "101", "ett\u00ADhundra\u00ADett" },
+            { "123", "ett\u00ADhundra\u00ADtjugo\u00ADtre" },
+            { "1,001", "ettusen ett" },
+            { "1,100", "ettusen ett\u00ADhundra" },
+            { "1,101", "ettusen ett\u00ADhundra\u00ADett" },
+            { "1,234", "ettusen tv\u00e5\u00ADhundra\u00ADtrettio\u00ADfyra" },
+            { "10,001", "tio\u00ADtusen ett" },
+            { "11,000", "elva\u00ADtusen" },
+            { "12,000", "tolv\u00ADtusen" },
+            { "20,000", "tjugo-tusen" },
+            { "21,000", "tjugo\u00ADett-tusen" },
+            { "21,001", "tjugo\u00ADett-tusen ett" },
+            { "200,000", "tv\u00e5\u00ADhundra-tusen" },
+            { "201,000", "tv\u00e5\u00ADhundra\u00ADett-tusen" },
+            { "200,200", "tv\u00e5\u00ADhundra-tusen tv\u00e5\u00ADhundra" },
+            { "2,002,000", "tv\u00e5 miljoner tv\u00e5\u00ADtusen" },
+            { "12,345,678", "tolv miljoner tre\u00ADhundra\u00ADfyrtio\u00ADfem-tusen sex\u00ADhundra\u00ADsjuttio\u00AD\u00e5tta" },
+            { "123,456.789", "ett\u00ADhundra\u00ADtjugo\u00ADtre-tusen fyra\u00ADhundra\u00ADfemtio\u00ADsex komma sju \u00e5tta nio" },
+            { "-12,345.678", "minus tolv\u00ADtusen tre\u00ADhundra\u00ADfyrtio\u00ADfem komma sex sju \u00e5tta" }
+        };
+
+        logln("testing default rules");
+        doTest(formatter, testDataDefault, true);
+
+        String[][] testDataNeutrum = {
+            { "101", "ett\u00adhundra\u00aden" },
+            { "1,001", "ettusen en" },
+            { "1,101", "ettusen ett\u00adhundra\u00aden" },
+            { "10,001", "tio\u00adtusen en" },
+            { "21,001", "tjugo\u00aden\u00adtusen en" }
+        };
+
+        formatter.setDefaultRuleSet("%spellout-cardinal-neutre");
+        logln("testing neutrum rules");
+        doTest(formatter, testDataNeutrum, true);
+
+        String[][] testDataYear = {
+            { "101", "ett\u00adhundra\u00adett" },
+            { "900", "nio\u00adhundra" },
+            { "1,001", "ettusen ett" },
+            { "1,100", "elva\u00adhundra" },
+            { "1,101", "elva\u00adhundra\u00adett" },
+            { "1,234", "tolv\u00adhundra\u00adtrettio\u00adfyra" },
+            { "2,001", "tjugo\u00adhundra\u00adett" },
+            { "10,001", "tio\u00adtusen ett" }
+        };
+
+        formatter.setDefaultRuleSet("%spellout-numbering-year");
+        logln("testing year rules");
+        doTest(formatter, testDataYear, true);
+    }
+
+    public void TestBigNumbers() {
+        BigInteger bigI = new BigInteger("1234567890", 10);
+        StringBuffer buf = new StringBuffer();
+        RuleBasedNumberFormat fmt = new RuleBasedNumberFormat(RuleBasedNumberFormat.SPELLOUT);
+        fmt.format(bigI, buf, null);
+        logln("big int: " + buf.toString());
+
+//#if defined(FOUNDATION10)
+//#else
+        buf.setLength(0);
+        java.math.BigDecimal bigD = new java.math.BigDecimal(bigI);
+        fmt.format(bigD, buf, null);
+        logln("big dec: " + buf.toString());
+//#endif
+    }
+
+  public void TestTrailingSemicolon() {
+    String thaiRules = 
+        "%default:\n" +
+        "  -x: \u0e25\u0e1a>>;\n" +
+        "  x.x: <<\u0e08\u0e38\u0e14>>>;\n" +
+        "  \u0e28\u0e39\u0e19\u0e22\u0e4c; \u0e2b\u0e19\u0e36\u0e48\u0e07; \u0e2a\u0e2d\u0e07; \u0e2a\u0e32\u0e21;\n" +
+        "  \u0e2a\u0e35\u0e48; \u0e2b\u0e49\u0e32; \u0e2b\u0e01; \u0e40\u0e08\u0e47\u0e14; \u0e41\u0e1b\u0e14;\n" +
+        "  \u0e40\u0e01\u0e49\u0e32; \u0e2a\u0e34\u0e1a; \u0e2a\u0e34\u0e1a\u0e40\u0e2d\u0e47\u0e14;\n" +
+        "  \u0e2a\u0e34\u0e1a\u0e2a\u0e2d\u0e07; \u0e2a\u0e34\u0e1a\u0e2a\u0e32\u0e21;\n" +
+        "  \u0e2a\u0e34\u0e1a\u0e2a\u0e35\u0e48; \u0e2a\u0e34\u0e1a\u0e2b\u0e49\u0e32;\n" +
+        "  \u0e2a\u0e34\u0e1a\u0e2b\u0e01; \u0e2a\u0e34\u0e1a\u0e40\u0e08\u0e47\u0e14;\n" +
+        "  \u0e2a\u0e34\u0e1a\u0e41\u0e1b\u0e14; \u0e2a\u0e34\u0e1a\u0e40\u0e01\u0e49\u0e32;\n" +
+        "  20: \u0e22\u0e35\u0e48\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +
+        "  30: \u0e2a\u0e32\u0e21\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +
+        "  40: \u0e2a\u0e35\u0e48\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +
+        "  50: \u0e2b\u0e49\u0e32\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +
+        "  60: \u0e2b\u0e01\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +
+        "  70: \u0e40\u0e08\u0e47\u0e14\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +
+        "  80: \u0e41\u0e1b\u0e14\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +
+        "  90: \u0e40\u0e01\u0e49\u0e32\u0e2a\u0e34\u0e1a[>%%alt-ones>];\n" +
+        "  100: <<\u0e23\u0e49\u0e2d\u0e22[>>];\n" +
+        "  1000: <<\u0e1e\u0e31\u0e19[>>];\n" +
+        "  10000: <<\u0e2b\u0e21\u0e37\u0e48\u0e19[>>];\n" +
+        "  100000: <<\u0e41\u0e2a\u0e19[>>];\n" +
+        "  1,000,000: <<\u0e25\u0e49\u0e32\u0e19[>>];\n" +
+        "  1,000,000,000: <<\u0e1e\u0e31\u0e19\u0e25\u0e49\u0e32\u0e19[>>];\n" +
+        "  1,000,000,000,000: <<\u0e25\u0e49\u0e32\u0e19\u0e25\u0e49\u0e32\u0e19[>>];\n" +
+        "  1,000,000,000,000,000: =#,##0=;\n" +
+        "%%alt-ones:\n" +
+        "  \u0e28\u0e39\u0e19\u0e22\u0e4c;\n" +
+        "  \u0e40\u0e2d\u0e47\u0e14;\n" +
+        "  =%default=;\n ; ;; ";
+
+        RuleBasedNumberFormat formatter
+            = new RuleBasedNumberFormat(thaiRules, new Locale("th", "TH", ""));
+
+        String[][] testData = {
+            { "0", "\u0e28\u0e39\u0e19\u0e22\u0e4c" },
+            { "1", "\u0e2b\u0e19\u0e36\u0e48\u0e07" },
+            { "123.45", "\u0e2b\u0e19\u0e36\u0e48\u0e07\u0e23\u0e49\u0e2d\u0e22\u0e22\u0e35\u0e48\u0e2a\u0e34\u0e1a\u0e2a\u0e32\u0e21\u0e08\u0e38\u0e14\u0e2a\u0e35\u0e48\u0e2b\u0e49\u0e32" }
+        };
+        
+        doTest(formatter, testData, true);
+    }
+
+    public void TestSmallValues() {
+    String[][] testData = {
+        { "0.001", "zero point zero zero one" },
+        { "0.0001", "zero point zero zero zero one" },
+        { "0.00001", "zero point zero zero zero zero one" },
+        { "0.000001", "zero point zero zero zero zero zero one" },
+        { "0.0000001", "zero point zero zero zero zero zero zero one" },
+        { "0.00000001", "zero point zero zero zero zero zero zero zero one" },
+        { "0.000000001", "zero point zero zero zero zero zero zero zero zero one" },
+        { "0.0000000001", "zero point zero zero zero zero zero zero zero zero zero one" },
+        { "0.00000000001", "zero point zero zero zero zero zero zero zero zero zero zero one" },
+        { "0.000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero one" },
+        { "0.0000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero one" },
+        { "0.00000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero zero one" },
+        { "0.000000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero zero zero one" },
+        { "10,000,000.001", "ten million point zero zero one" },
+        { "10,000,000.0001", "ten million point zero zero zero one" },
+        { "10,000,000.00001", "ten million point zero zero zero zero one" },
+        { "10,000,000.000001", "ten million point zero zero zero zero zero one" },
+        { "10,000,000.0000001", "ten million point zero zero zero zero zero zero one" },
+        { "10,000,000.00000001", "ten million point zero zero zero zero zero zero zero one" },
+        { "10,000,000.000000002", "ten million point zero zero zero zero zero zero zero zero two" },
+        { "10,000,000", "ten million" },
+        { "1,234,567,890.0987654", "one billion two hundred thirty-four million five hundred sixty-seven thousand eight hundred ninety point zero nine eight seven six five four" },
+        { "123,456,789.9876543", "one hundred twenty-three million four hundred fifty-six thousand seven hundred eighty-nine point nine eight seven six five four three" },
+        { "12,345,678.87654321", "twelve million three hundred forty-five thousand six hundred seventy-eight point eight seven six five four three two one" },
+        { "1,234,567.7654321", "one million two hundred thirty-four thousand five hundred sixty-seven point seven six five four three two one" },
+        { "123,456.654321", "one hundred twenty-three thousand four hundred fifty-six point six five four three two one" },
+        { "12,345.54321", "twelve thousand three hundred forty-five point five four three two one" },
+        { "1,234.4321", "one thousand two hundred thirty-four point four three two one" },
+        { "123.321", "one hundred twenty-three point three two one" },
+        { "0.0000000011754944", "zero point zero zero zero zero zero zero zero zero one one seven five four nine four four" },
+        { "0.000001175494351", "zero point zero zero zero zero zero one one seven five four nine four three five one" },
+    };
+
+    RuleBasedNumberFormat formatter
+        = new RuleBasedNumberFormat(Locale.US, RuleBasedNumberFormat.SPELLOUT);
+    doTest(formatter, testData, true);
+    }
+
+    public void TestRuleSetDisplayName() {
+        ULocale.setDefault(ULocale.US);
+        String[][] localizations = new String[][] {
+            /* public rule sets*/
+            {"%simplified", "%default", "%ordinal"},
+            /* display names in "en_US" locale*/
+            {"en_US", "Simplified", "Default", "Ordinal"},
+            /* display names in "zh_Hans" locale*/
+            {"zh_Hans", "\u7B80\u5316", "\u7F3A\u7701",  "\u5E8F\u5217"},
+            /* display names in a fake locale*/
+            {"foo_Bar_BAZ", "Simplified", "Default", "Ordinal"}
+        };
+        
+        //Construct RuleBasedNumberFormat by rule sets and localizations list
+        RuleBasedNumberFormat formatter
+            = new RuleBasedNumberFormat(ukEnglish, localizations, ULocale.US);
+        RuleBasedNumberFormat f2= new RuleBasedNumberFormat(ukEnglish, localizations);
+        assertTrue("Check the two formatters' equality", formatter.equals(f2));        
+
+        //get displayName by name
+        String[] ruleSetNames = formatter.getRuleSetNames();
+        for (int i=0; i<ruleSetNames.length; i++) {
+            logln("Rule set name: " + ruleSetNames[i]);
+            String RSName_defLoc = formatter.getRuleSetDisplayName(ruleSetNames[i]);
+            assertEquals("Display name in default locale", localizations[1][i+1], RSName_defLoc);
+            String RSName_loc = formatter.getRuleSetDisplayName(ruleSetNames[i], ULocale.CHINA);
+            assertEquals("Display name in Chinese", localizations[2][i+1], RSName_loc);
+        }
+                
+        // getDefaultRuleSetName
+        String defaultRS = formatter.getDefaultRuleSetName();
+        //you know that the default rule set is %simplified according to rule sets string ukEnglish
+        assertEquals("getDefaultRuleSetName", "%simplified", defaultRS);
+        
+        //get locales of localizations
+        ULocale[] locales = formatter.getRuleSetDisplayNameLocales();
+        for (int i=0; i<locales.length; i++) {
+            logln(locales[i].getName());
+        }
+        
+        //get displayNames
+        String[] RSNames_defLoc = formatter.getRuleSetDisplayNames();
+        for (int i=0; i<RSNames_defLoc.length; i++) {
+            assertEquals("getRuleSetDisplayNames in default locale", localizations[1][i+1], RSNames_defLoc[i]);
+        }
+        
+        String[] RSNames_loc = formatter.getRuleSetDisplayNames(ULocale.UK);
+        for (int i=0; i<RSNames_loc.length; i++) {
+            assertEquals("getRuleSetDisplayNames in English", localizations[1][i+1], RSNames_loc[i]);
+        }    
+        
+        RSNames_loc = formatter.getRuleSetDisplayNames(ULocale.CHINA);
+        for (int i=0; i<RSNames_loc.length; i++) {
+            assertEquals("getRuleSetDisplayNames in Chinese", localizations[2][i+1], RSNames_loc[i]);
+        }        
+
+        RSNames_loc = formatter.getRuleSetDisplayNames(new ULocale("foo_Bar_BAZ"));
+        for (int i=0; i<RSNames_loc.length; i++) {
+            assertEquals("getRuleSetDisplayNames in fake locale", localizations[3][i+1], RSNames_loc[i]);
+        }              
+    }
+
+    public void TestAllLocales() {
+        StringBuffer errors = null;
+        ULocale[] locales = ULocale.getAvailableLocales();
+        String[] names = {
+            " (spellout) ",
+            " (ordinal)  ",
+            " (duration) "
+        };
+        double[] numbers = {45.678, 1, 2, 10, 11, 100, 110, 200, 1000, 1111, -1111};
+        Random r = null;
+
+        // RBNF parse is extremely slow when lenient option is enabled.
+        // For non-exhaustive mode, we only test a few locales.
+        // "nl_NL", "be" had crash problem reported by #6534
+        String[] parseLocales = {"en_US", "nl_NL", "be"};
+
+        for (int i = 0; i < locales.length; ++i) {
+            ULocale loc = locales[i];
+            int count = numbers.length;
+            boolean testParse = true;
+            if (getInclusion() <= 5) {
+                testParse = false;
+                for (int k = 0; k < parseLocales.length; k++) {
+                    if (loc.toString().equals(parseLocales[k])) {
+                        testParse = true;
+                        break;
+                    }
+                }
+            } else {
+                //RBNF parse is too slow.  Increase count only for debugging purpose for now.
+                //count = 100;
+            }
+
+            for (int j = 0; j < 3; ++j) {
+                RuleBasedNumberFormat fmt = new RuleBasedNumberFormat(loc, j+1);
+
+                for (int c = 0; c < count; c++) {
+                    double n;
+                    if (c < numbers.length) {
+                        n = numbers[c];
+                    } else {
+                        if (r == null) {
+                            r = createRandom();
+                        }
+                        n = ((int)(r.nextInt(10000) - 3000)) / 16d;
+                    }
+
+                    String s = fmt.format(n);
+                    logln(loc.getName() + names[j] + "success format: " + n + " -> " + s);
+
+                    if (testParse) {
+                        // We do not validate the result in this test case,
+                        // because there are cases which do not round trip by design.
+                        try {
+                            // non-lenient parse
+                            fmt.setLenientParseMode(false);
+                            Number num = fmt.parse(s);
+                            logln(loc.getName() + names[j] + "success parse: " + s + " -> " + num);
+
+                            // lenient parse
+                            fmt.setLenientParseMode(true);
+                            num = fmt.parse(s);
+                            logln(loc.getName() + names[j] + "success parse (lenient): " + s + " -> " + num);
+                        } catch (ParseException pe) {
+                            String msg = loc.getName() + names[j] + "ERROR:" + pe.getMessage();
+                            logln(msg);
+                            if (errors == null) {
+                                errors = new StringBuffer();
+                            }
+                            errors.append("\n" + msg);
+                        }
+                    }
+                }
+            }
+        }
+        if (errors != null) {
+            //TODO: We need to fix parse problems - see #6895 / #6896
+            //errln(errors.toString());
+            logln(errors.toString());
+        }
+    }
+
+    void doTest(RuleBasedNumberFormat formatter, String[][] testData,
+                boolean testParsing) {
+    //        NumberFormat decFmt = NumberFormat.getInstance(Locale.US);
+    NumberFormat decFmt = new DecimalFormat("#,###.################");
+        try {
+            for (int i = 0; i < testData.length; i++) {
+                String number = testData[i][0];
+                String expectedWords = testData[i][1];
+                logln("test[" + i + "] number: " + number + " target: " + expectedWords);
+                Number num = decFmt.parse(number);
+                String actualWords = formatter.format(num);
+
+                if (!actualWords.equals(expectedWords)) {
+                    errln("Spot check format failed: for " + number + ", expected\n    "
+                          + expectedWords + ", but got\n    " +
+                          actualWords);
+                }
+                else if (testParsing) {
+                    String actualNumber = decFmt.format(formatter
+                                                        .parse(actualWords));
+
+                    if (!actualNumber.equals(number)) {
+                        errln("Spot check parse failed: for " + actualWords +
+                              ", expected " + number + ", but got " +
+                              actualNumber);
+                    }
+                }
+            }
+        }
+        catch (Throwable e) {
+            e.printStackTrace();
+            errln("Test failed with exception: " + e.toString());
+        }
+    }
+
+    void doLenientParseTest(RuleBasedNumberFormat formatter,
+                            String[][] testData) {
+        NumberFormat decFmt = NumberFormat.getInstance(Locale.US);
+
+        try {
+            for (int i = 0; i < testData.length; i++) {
+                String words = testData[i][0];
+                String expectedNumber = testData[i][1];
+                String actualNumber = decFmt.format(formatter.parse(words));
+
+                if (!actualNumber.equals(expectedNumber)) {
+                    errln("Lenient-parse spot check failed: for "
+                          + words + ", expected " + expectedNumber
+                          + ", but got " + actualNumber);
+                }
+            }
+        }
+        catch (Throwable e) {
+            errln("Test failed with exception: " + e.toString());
+            e.printStackTrace();
+        }
+    }
+
+
+    /**
+     * Spellout rules for U.K. English.  
+     * I borrow the rule sets for TestRuleSetDisplayName()
+     */
+    public static final String ukEnglish =
+        "%simplified:\n"
+        + "    -x: minus >>;\n"
+        + "    x.x: << point >>;\n"
+        + "    zero; one; two; three; four; five; six; seven; eight; nine;\n"
+        + "    ten; eleven; twelve; thirteen; fourteen; fifteen; sixteen;\n"
+        + "        seventeen; eighteen; nineteen;\n"
+        + "    20: twenty[->>];\n"
+        + "    30: thirty[->>];\n"
+        + "    40: forty[->>];\n"
+        + "    50: fifty[->>];\n"
+        + "    60: sixty[->>];\n"
+        + "    70: seventy[->>];\n"
+        + "    80: eighty[->>];\n"
+        + "    90: ninety[->>];\n"
+        + "    100: << hundred[ >>];\n"
+        + "    1000: << thousand[ >>];\n"
+        + "    1,000,000: << million[ >>];\n"
+        + "    1,000,000,000,000: << billion[ >>];\n"
+        + "    1,000,000,000,000,000: =#,##0=;\n"
+        + "%alt-teens:\n"
+        + "    =%simplified=;\n"
+        + "    1000>: <%%alt-hundreds<[ >>];\n"
+        + "    10,000: =%simplified=;\n"
+        + "    1,000,000: << million[ >%simplified>];\n"
+        + "    1,000,000,000,000: << billion[ >%simplified>];\n"
+        + "    1,000,000,000,000,000: =#,##0=;\n"
+        + "%%alt-hundreds:\n"
+        + "    0: SHOULD NEVER GET HERE!;\n"
+        + "    10: <%simplified< thousand;\n"
+        + "    11: =%simplified= hundred>%%empty>;\n"
+        + "%%empty:\n"
+        + "    0:;"
+        + "%ordinal:\n"
+        + "    zeroth; first; second; third; fourth; fifth; sixth; seventh;\n"
+        + "        eighth; ninth;\n"
+        + "    tenth; eleventh; twelfth; thirteenth; fourteenth;\n"
+        + "        fifteenth; sixteenth; seventeenth; eighteenth;\n"
+        + "        nineteenth;\n"
+        + "    twentieth; twenty->>;\n"
+        + "    30: thirtieth; thirty->>;\n"
+        + "    40: fortieth; forty->>;\n"
+        + "    50: fiftieth; fifty->>;\n"
+        + "    60: sixtieth; sixty->>;\n"
+        + "    70: seventieth; seventy->>;\n"
+        + "    80: eightieth; eighty->>;\n"
+        + "    90: ninetieth; ninety->>;\n"
+        + "    100: <%simplified< hundredth; <%simplified< hundred >>;\n"
+        + "    1000: <%simplified< thousandth; <%simplified< thousand >>;\n"
+        + "    1,000,000: <%simplified< millionth; <%simplified< million >>;\n"
+        + "    1,000,000,000,000: <%simplified< billionth;\n"
+        + "        <%simplified< billion >>;\n"
+        + "    1,000,000,000,000,000: =#,##0=;"
+        + "%default:\n"
+        + "    -x: minus >>;\n"
+        + "    x.x: << point >>;\n"
+        + "    =%simplified=;\n"
+        + "    100: << hundred[ >%%and>];\n"
+        + "    1000: << thousand[ >%%and>];\n"
+        + "    100,000>>: << thousand[>%%commas>];\n"
+        + "    1,000,000: << million[>%%commas>];\n"
+        + "    1,000,000,000,000: << billion[>%%commas>];\n"
+        + "    1,000,000,000,000,000: =#,##0=;\n"
+        + "%%and:\n"
+        + "    and =%default=;\n"
+        + "    100: =%default=;\n"
+        + "%%commas:\n"
+        + "    ' and =%default=;\n"
+        + "    100: , =%default=;\n"
+        + "    1000: , <%default< thousand, >%default>;\n"
+        + "    1,000,000: , =%default=;"
+        + "%%lenient-parse:\n"
+        + "    & ' ' , ',' ;\n";
+
+}
+