]> gitweb.fperrin.net Git - Dictionary.git/blobdiff - jars/icu4j-4_2_1-src/src/com/ibm/icu/text/NumberFormat.java
go
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / icu / text / NumberFormat.java
old mode 100755 (executable)
new mode 100644 (file)
index b4774c9..dc60c81
-//##header\r
-/*\r
- *******************************************************************************\r
- * Copyright (C) 1996-2009, International Business Machines Corporation and    *\r
- * others. All Rights Reserved.                                                *\r
- *******************************************************************************\r
- */\r
-\r
-package com.ibm.icu.text;\r
-\r
-import java.io.IOException;\r
-import java.io.InvalidObjectException;\r
-import java.io.ObjectInputStream;\r
-import java.io.ObjectOutputStream;\r
-import java.math.BigInteger;\r
-import java.text.FieldPosition;\r
-import java.text.ParseException;\r
-import java.text.ParsePosition;\r
-import java.util.Collections;\r
-import java.util.Locale;\r
-import java.util.MissingResourceException;\r
-import java.util.Set;\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-import java.text.Format;\r
-//#endif\r
-\r
-import com.ibm.icu.impl.ICUResourceBundle;\r
-import com.ibm.icu.impl.Utility;\r
-import com.ibm.icu.util.Currency;\r
-import com.ibm.icu.util.CurrencyAmount;\r
-import com.ibm.icu.util.ULocale;\r
-import com.ibm.icu.util.UResourceBundle;\r
-\r
-// this is an enhanced version that is based on the standard version in the JDK\r
-/**\r
- * <code>NumberFormat</code> is the abstract base class for all number\r
- * formats. This class provides the interface for formatting and parsing\r
- * numbers. <code>NumberFormat</code> also provides methods for determining\r
- * which locales have number formats, and what their names are.\r
- *\r
- * <code>NumberFormat</code> helps you to format and parse numbers for any locale.\r
- * Your code can be completely independent of the locale conventions for\r
- * decimal points, thousands-separators, or even the particular decimal\r
- * digits used, or whether the number format is even decimal.\r
- *\r
- * <p>\r
- * To format a number for the current Locale, use one of the factory\r
- * class methods:\r
- * <blockquote>\r
- * <pre>\r
- *  myString = NumberFormat.getInstance().format(myNumber);\r
- * </pre>\r
- * </blockquote>\r
- * If you are formatting multiple numbers, it is\r
- * more efficient to get the format and use it multiple times so that\r
- * the system doesn't have to fetch the information about the local\r
- * language and country conventions multiple times.\r
- * <blockquote>\r
- * <pre>\r
- * NumberFormat nf = NumberFormat.getInstance();\r
- * for (int i = 0; i < a.length; ++i) {\r
- *     output.println(nf.format(myNumber[i]) + "; ");\r
- * }\r
- * </pre>\r
- * </blockquote>\r
- * To format a number for a different Locale, specify it in the\r
- * call to <code>getInstance</code>.\r
- * <blockquote>\r
- * <pre>\r
- * NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);\r
- * </pre>\r
- * </blockquote>\r
- * You can also use a <code>NumberFormat</code> to parse numbers:\r
- * <blockquote>\r
- * <pre>\r
- * myNumber = nf.parse(myString);\r
- * </pre>\r
- * </blockquote>\r
- * Use <code>getInstance</code> or <code>getNumberInstance</code> to get the\r
- * normal number format. Use <code>getIntegerInstance</code> to get an\r
- * integer number format. Use <code>getCurrencyInstance</code> to get the\r
- * currency number format. And use <code>getPercentInstance</code> to get a\r
- * format for displaying percentages. With this format, a fraction like\r
- * 0.53 is displayed as 53%.\r
- *\r
- * <p>\r
- * Starting from ICU 4.2, you can use getInstance() by passing in a 'style'\r
- * as parameter to get the correct instance. \r
- * For example, \r
- * use getInstance(...NUMBERSTYLE) to get the normal number format,\r
- * getInstance(...PERCENTSTYLE) to get a format for displaying percentage,\r
- * getInstance(...SCIENTIFICSTYLE) to get a format for displaying scientific number,\r
- * getInstance(...INTEGERSTYLE) to get an integer number format,\r
- * getInstance(...CURRENCYSTYLE) to get the currency number format, \r
- * in which the currency is represented by its symbol, for example, "$3.00".\r
- * getInstance(...ISOCURRENCYSTYLE)  to get the currency number format, \r
- * in which the currency is represented by its ISO code, for example "USD3.00".\r
- * getInstance(...PLURALCURRENCYSTYLE) to get the currency number format,\r
- * in which the currency is represented by its full name in plural format,\r
- * for example, "3.00 US dollars" or "1.00 US dollar".\r
- *\r
- *\r
- * <p>\r
- * You can also control the display of numbers with such methods as\r
- * <code>setMinimumFractionDigits</code>.\r
- * If you want even more control over the format or parsing,\r
- * or want to give your users more control,\r
- * you can try casting the <code>NumberFormat</code> you get from the factory methods\r
- * to a <code>DecimalFormat</code>. This will work for the vast majority\r
- * of locales; just remember to put it in a <code>try</code> block in case you\r
- * encounter an unusual one.\r
- *\r
- * <p>\r
- * NumberFormat is designed such that some controls\r
- * work for formatting and others work for parsing.  The following is\r
- * the detailed description for each these control methods,\r
- * <p>\r
- * setParseIntegerOnly : only affects parsing, e.g.\r
- * if true,  "3456.78" -> 3456 (and leaves the parse position just after '6')\r
- * if false, "3456.78" -> 3456.78 (and leaves the parse position just after '8')\r
- * This is independent of formatting.  If you want to not show a decimal point\r
- * where there might be no digits after the decimal point, use\r
- * setDecimalSeparatorAlwaysShown on DecimalFormat.\r
- * <p>\r
- * You can also use forms of the <code>parse</code> and <code>format</code>\r
- * methods with <code>ParsePosition</code> and <code>FieldPosition</code> to\r
- * allow you to:\r
- * <ul>\r
- * <li> progressively parse through pieces of a string\r
- * <li> align the decimal point and other areas\r
- * </ul>\r
- * For example, you can align numbers in two ways:\r
- * <ol>\r
- * <li> If you are using a monospaced font with spacing for alignment,\r
- *      you can pass the <code>FieldPosition</code> in your format call, with\r
- *      <code>field</code> = <code>INTEGER_FIELD</code>. On output,\r
- *      <code>getEndIndex</code> will be set to the offset between the\r
- *      last character of the integer and the decimal. Add\r
- *      (desiredSpaceCount - getEndIndex) spaces at the front of the string.\r
- *\r
- * <li> If you are using proportional fonts,\r
- *      instead of padding with spaces, measure the width\r
- *      of the string in pixels from the start to <code>getEndIndex</code>.\r
- *      Then move the pen by\r
- *      (desiredPixelWidth - widthToAlignmentPoint) before drawing the text.\r
- *      It also works where there is no decimal, but possibly additional\r
- *      characters at the end, e.g., with parentheses in negative\r
- *      numbers: "(12)" for -12.\r
- * </ol>\r
- *\r
- * <h4>Synchronization</h4>\r
- * <p>\r
- * Number formats are generally not synchronized. It is recommended to create \r
- * separate format instances for each thread. If multiple threads access a format\r
- * concurrently, it must be synchronized externally. \r
- * <p>\r
- *\r
- * <h4>DecimalFormat</h4>\r
- * <p>DecimalFormat is the concrete implementation of NumberFormat, and the\r
- * NumberFormat API is essentially an abstraction from DecimalFormat's API.\r
- * Refer to DecimalFormat for more information about this API.</p>\r
- *\r
- * see          DecimalFormat\r
- * see          java.text.ChoiceFormat\r
- * @author       Mark Davis\r
- * @author       Helena Shih\r
- * @author       Alan Liu\r
- * @stable ICU 2.0\r
- */\r
-public abstract class NumberFormat extends UFormat {\r
-\r
-    /**\r
-     * Constants to specify normal number style of format.\r
-     * @draft ICU 4.2\r
-     * @provisional This API might change or be removed in a future release.\r
-     */\r
-    public static final int NUMBERSTYLE = 0;\r
-    /**\r
-     * Constants to specify currency style of format which uses currency symbol\r
-     * to represent currency, for example: "$3.00".\r
-     * @draft ICU 4.2\r
-     * @provisional This API might change or be removed in a future release.\r
-     */\r
-    public static final int CURRENCYSTYLE = 1;\r
-    /**\r
-     * Constants to specify a style of format to display percent.\r
-     * @draft ICU 4.2\r
-     * @provisional This API might change or be removed in a future release.\r
-     */\r
-    public static final int PERCENTSTYLE = 2;\r
-    /**\r
-     * Constants to specify a style of format to display scientific number.\r
-     * @draft ICU 4.2\r
-     * @provisional This API might change or be removed in a future release.\r
-     */\r
-    public static final int SCIENTIFICSTYLE = 3;\r
-    /**\r
-     * Constants to specify a integer number style format.\r
-     * @draft ICU 4.2\r
-     * @provisional This API might change or be removed in a future release.\r
-     */\r
-    public static final int INTEGERSTYLE = 4;\r
-    /**\r
-     * Constants to specify currency style of format which uses currency \r
-     * ISO code to represent currency, for example: "USD3.00".\r
-     * @draft ICU 4.2\r
-     * @provisional This API might change or be removed in a future release.\r
-     */\r
-    public static final int ISOCURRENCYSTYLE = 5;\r
-    /**\r
-     * Constants to specify currency style of format which uses currency \r
-     * long name with plural format to represent currency, for example,\r
-     * "3.00 US Dollars".\r
-     * @draft ICU 4.2\r
-     * @provisional This API might change or be removed in a future release.\r
-     */\r
-    public static final int PLURALCURRENCYSTYLE = 6;\r
-\r
-    /**\r
-     * Field constant used to construct a FieldPosition object. Signifies that\r
-     * the position of the integer part of a formatted number should be returned.\r
-     * @see java.text.FieldPosition\r
-     * @stable ICU 2.0\r
-     */\r
-    public static final int INTEGER_FIELD = 0;\r
-\r
-    /**\r
-     * Field constant used to construct a FieldPosition object. Signifies that\r
-     * the position of the fraction part of a formatted number should be returned.\r
-     * @see java.text.FieldPosition\r
-     * @stable ICU 2.0\r
-     */\r
-    public static final int FRACTION_FIELD = 1;\r
-\r
-    // changed in ICU4J\r
-    /**\r
-     * Format an object.  Change: recognizes <code>BigInteger</code>\r
-     * and <code>BigDecimal</code> objects.\r
-     * @stable ICU 2.0\r
-     */\r
-    public StringBuffer format(Object number,\r
-                               StringBuffer toAppendTo,\r
-                               FieldPosition pos)\r
-    {\r
-        if (number instanceof Long) {\r
-            return format(((Long)number).longValue(), toAppendTo, pos);\r
-        } else if (number instanceof BigInteger) {\r
-            return format((BigInteger) number, toAppendTo, pos);\r
-//#if defined(FOUNDATION10)\r
-//#else\r
-        } else if (number instanceof java.math.BigDecimal) {\r
-            return format((java.math.BigDecimal) number, toAppendTo, pos);\r
-//#endif\r
-        } else if (number instanceof com.ibm.icu.math.BigDecimal) {\r
-            return format((com.ibm.icu.math.BigDecimal) number, toAppendTo, pos);\r
-        } else if (number instanceof CurrencyAmount) {\r
-            return format((CurrencyAmount)number, toAppendTo, pos);\r
-        } else if (number instanceof Number) {\r
-            return format(((Number)number).doubleValue(), toAppendTo, pos);\r
-        } else {\r
-            throw new IllegalArgumentException("Cannot format given Object as a Number");\r
-        }\r
-    }\r
-\r
-    /**\r
-     * @stable ICU 2.0\r
-     */\r
-    public final Object parseObject(String source,\r
-                                    ParsePosition parsePosition)\r
-    {\r
-        return parse(source, parsePosition);\r
-    }\r
-\r
-    /**\r
-     * Specialization of format.\r
-     * @see java.text.Format#format(Object)\r
-     * @stable ICU 2.0\r
-     */\r
-    public final String format(double number) {\r
-        return format(number,new StringBuffer(),\r
-                      new FieldPosition(0)).toString();\r
-    }\r
-\r
-    /**\r
-     * Specialization of format.\r
-     * @see java.text.Format#format(Object)\r
-     * @stable ICU 2.0\r
-     */\r
-    public final String format(long number) {\r
-        StringBuffer buf = new StringBuffer(19);\r
-        FieldPosition pos = new FieldPosition(0);\r
-        format(number, buf, pos);\r
-        return buf.toString();\r
-    }\r
-    \r
-    // [NEW]\r
-    /**\r
-     * Convenience method to format a BigInteger.\r
-     * @stable ICU 2.0\r
-     */\r
-    public final String format(BigInteger number) {\r
-        return format(number, new StringBuffer(),\r
-                      new FieldPosition(0)).toString();\r
-    }\r
-\r
-//#if defined(FOUNDATION10)\r
-//#else\r
-    // [NEW]\r
-    /**\r
-     * Convenience method to format a BigDecimal.\r
-     * @stable ICU 2.0\r
-     */\r
-    public final String format(java.math.BigDecimal number) {\r
-        return format(number, new StringBuffer(),\r
-                      new FieldPosition(0)).toString();\r
-    }\r
-//#endif\r
-\r
-    // [NEW]\r
-    /**\r
-     * Convenience method to format an ICU BigDecimal.\r
-     * @stable ICU 2.0\r
-     */\r
-    public final String format(com.ibm.icu.math.BigDecimal number) {\r
-        return format(number, new StringBuffer(),\r
-                      new FieldPosition(0)).toString();\r
-    }\r
-\r
-    // [NEW]\r
-    /**\r
-     * Convenience method to format a CurrencyAmount.\r
-     * @stable ICU 3.0\r
-     */\r
-    public final String format(CurrencyAmount currAmt) {\r
-        return format(currAmt, new StringBuffer(),\r
-                      new FieldPosition(0)).toString();\r
-    }\r
-\r
-    /**\r
-     * Specialization of format.\r
-     * @see java.text.Format#format(Object, StringBuffer, FieldPosition)\r
-     * @stable ICU 2.0\r
-     */\r
-    public abstract StringBuffer format(double number,\r
-                                        StringBuffer toAppendTo,\r
-                                        FieldPosition pos);\r
-\r
-    /**\r
-     * Specialization of format.\r
-     * @see java.text.Format#format(Object, StringBuffer, FieldPosition)\r
-     * @stable ICU 2.0\r
-     */\r
-    public abstract StringBuffer format(long number,\r
-                                        StringBuffer toAppendTo,\r
-                                        FieldPosition pos);\r
-    // [NEW] \r
-    /**\r
-     * Format a BigInteger.\r
-     * @see java.text.Format#format(Object, StringBuffer, FieldPosition)\r
-     * @stable ICU 2.0\r
-     */\r
-    public abstract StringBuffer format(BigInteger number,\r
-                                        StringBuffer toAppendTo,\r
-                                        FieldPosition pos); \r
-//#if defined(FOUNDATION10)\r
-//#else\r
-    \r
-    // [NEW]\r
-    /**\r
-     * Format a BigDecimal.\r
-     * @see java.text.Format#format(Object, StringBuffer, FieldPosition)\r
-     * @stable ICU 2.0\r
-     */\r
-    public abstract StringBuffer format(java.math.BigDecimal number,\r
-                                        StringBuffer toAppendTo,\r
-                                        FieldPosition pos);\r
-//#endif\r
-\r
-    // [NEW]\r
-    /**\r
-     * Format a BigDecimal.\r
-     * @see java.text.Format#format(Object, StringBuffer, FieldPosition)\r
-     * @stable ICU 2.0\r
-     */\r
-    public abstract StringBuffer format(com.ibm.icu.math.BigDecimal number,\r
-                                        StringBuffer toAppendTo,\r
-                                        FieldPosition pos);\r
-    // [NEW]\r
-    /**\r
-     * Format a CurrencyAmount.\r
-     * @see java.text.Format#format(Object, StringBuffer, FieldPosition)\r
-     * @stable ICU 3.0\r
-     */\r
-    public StringBuffer format(CurrencyAmount currAmt,\r
-                               StringBuffer toAppendTo,\r
-                               FieldPosition pos) {\r
-        // Default implementation -- subclasses may override\r
-        Currency save = getCurrency(), curr = currAmt.getCurrency();\r
-        boolean same = curr.equals(save);\r
-        if (!same) setCurrency(curr);\r
-        format(currAmt.getNumber(), toAppendTo, pos);\r
-        if (!same) setCurrency(save);\r
-        return toAppendTo;\r
-    }\r
-\r
-    /**\r
-     * Returns a Long if possible (e.g., within the range [Long.MIN_VALUE,\r
-     * Long.MAX_VALUE] and with no decimals), otherwise a Double.\r
-     * If IntegerOnly is set, will stop at a decimal\r
-     * point (or equivalent; e.g., for rational numbers "1 2/3", will stop\r
-     * after the 1).\r
-     * Does not throw an exception; if no object can be parsed, index is\r
-     * unchanged!\r
-     * @see #isParseIntegerOnly\r
-     * @see java.text.Format#parseObject(String, ParsePosition)\r
-     * @stable ICU 2.0\r
-     */\r
-    public abstract Number parse(String text, ParsePosition parsePosition);\r
-\r
-    /**\r
-     * Parses text from the beginning of the given string to produce a number.\r
-     * The method might not use the entire text of the given string.\r
-     *\r
-     * @param text A String whose beginning should be parsed.\r
-     * @return A Number parsed from the string.\r
-     * @exception ParseException if the beginning of the specified string \r
-     * cannot be parsed.\r
-     * @see #format\r
-     * @stable ICU 2.0\r
-     */\r
-    //Bug 4375399 [Richard/GCL]\r
-    public Number parse(String text) throws ParseException {\r
-        ParsePosition parsePosition = new ParsePosition(0);\r
-        Number result = parse(text, parsePosition);\r
-        if (parsePosition.getIndex() == 0) {\r
-            throw new ParseException("Unparseable number: \"" + text + '"',\r
-                                     parsePosition.getErrorIndex());\r
-        }\r
-        return result;\r
-    }\r
-\r
-    // [NEW]\r
-    /**\r
-     * Parses text from the given string as a CurrencyAmount.  Unlike\r
-     * the parse() method, this method will attempt to parse a generic\r
-     * currency name, searching for a match of this object's locale's\r
-     * currency display names, or for a 3-letter ISO currency code.\r
-     * This method will fail if this format is not a currency format,\r
-     * that is, if it does not contain the currency pattern symbol\r
-     * (U+00A4) in its prefix or suffix.\r
-     *\r
-     * @param text the string to parse\r
-     * @param pos input-output position; on input, the position within\r
-     * text to match; must have 0 <= pos.getIndex() < text.length();\r
-     * on output, the position after the last matched character. If\r
-     * the parse fails, the position in unchanged upon output.\r
-     * @return a CurrencyAmount, or null upon failure\r
-     * @internal\r
-     * @deprecated This API is ICU internal only.\r
-     */\r
-    CurrencyAmount parseCurrency(String text, ParsePosition pos) {\r
-        // Default implementation only -- subclasses should override\r
-        Number n = parse(text, pos);\r
-        return n == null ? null : new CurrencyAmount(n, getEffectiveCurrency());\r
-    }\r
-\r
-    /**\r
-     * Returns true if this format will parse numbers as integers only.\r
-     * For example in the English locale, with ParseIntegerOnly true, the\r
-     * string "1234." would be parsed as the integer value 1234 and parsing\r
-     * would stop at the "." character.  The decimal separator accepted\r
-     * by the parse operation is locale-dependent and determined by the\r
-     * subclass.\r
-     * @return true if this will parse integers only\r
-     * @stable ICU 2.0\r
-     */\r
-    public boolean isParseIntegerOnly() {\r
-        return parseIntegerOnly;\r
-    }\r
-\r
-    /**\r
-     * Sets whether or not numbers should be parsed as integers only.\r
-     * @param value true if this should parse integers only\r
-     * @see #isParseIntegerOnly\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setParseIntegerOnly(boolean value) {\r
-        parseIntegerOnly = value;\r
-    }\r
-\r
-    /**\r
-     * Sets whether strict parsing is in effect.  When this is true, the\r
-     * following conditions cause a parse failure (examples use the pattern "#,##0.#"):<ul>\r
-     * <li>Leading zeros<br>\r
-     * '00', '0123' fail the parse, but '0' and '0.001' pass</li>\r
-     * <li>Leading or doubled grouping separators<br>\r
-     * ',123' and '1,,234" fail</li>\r
-     * <li>Groups of incorrect length when grouping is used<br>\r
-     * '1,23' and '1234,567' fail, but '1234' passes</li>\r
-     * <li>Grouping separators used in numbers followed by exponents<br>\r
-     * '1,234E5' fails, but '1234E5' and '1,234E' pass ('E' is not an exponent when\r
-     * not followed by a number)</li>\r
-     * </ul>\r
-     * When strict parsing is off, leading zeros and all grouping separators are ignored.\r
-     * This is the default behavior.\r
-     * @param value True to enable strict parsing.  Default is false.\r
-     * @see #isParseStrict\r
-     * @stable ICU 3.6\r
-     */\r
-    public void setParseStrict(boolean value) {\r
-        parseStrict = value;\r
-    }\r
-\r
-    /**\r
-     * Return whether strict parsing is in effect.\r
-     * @return true if strict parsing is in effect\r
-     * @see #setParseStrict\r
-     * @stable ICU 3.6\r
-     */\r
-    public boolean isParseStrict() {\r
-        return parseStrict;\r
-    }\r
-\r
-    //============== Locale Stuff =====================\r
-\r
-    /**\r
-     * Returns the default number format for the current default locale.\r
-     * The default format is one of the styles provided by the other\r
-     * factory methods: getNumberInstance, getIntegerInstance,\r
-     * getCurrencyInstance or getPercentInstance.\r
-     * Exactly which one is locale-dependent.\r
-     * @stable ICU 2.0\r
-     */\r
-    //Bug 4408066 [Richard/GCL]\r
-    public final static NumberFormat getInstance() {\r
-        return getInstance(ULocale.getDefault(), NUMBERSTYLE);\r
-    }\r
-\r
-    /**\r
-     * Returns the default number format for the specified locale.\r
-     * The default format is one of the styles provided by the other\r
-     * factory methods: getNumberInstance, getCurrencyInstance or getPercentInstance.\r
-     * Exactly which one is locale-dependent.\r
-     * @stable ICU 2.0\r
-     */\r
-    public static NumberFormat getInstance(Locale inLocale) {\r
-        return getInstance(ULocale.forLocale(inLocale), NUMBERSTYLE);\r
-    }\r
-\r
-    /**\r
-     * Returns the default number format for the specified locale.\r
-     * The default format is one of the styles provided by the other\r
-     * factory methods: getNumberInstance, getCurrencyInstance or getPercentInstance.\r
-     * Exactly which one is locale-dependent.\r
-     * @stable ICU 3.2\r
-     */\r
-    public static NumberFormat getInstance(ULocale inLocale) {\r
-        return getInstance(inLocale, NUMBERSTYLE);\r
-    }\r
-\r
-    /**\r
-     * Returns a specific style number format for default locale.\r
-     * @param style  number format style\r
-     * @draft ICU 4.2\r
-     * @provisional This API might change or be removed in a future release.\r
-     */\r
-    public final static NumberFormat getInstance(int style) {\r
-        return getInstance(ULocale.getDefault(), style);\r
-    }\r
-\r
-    /**\r
-     * Returns a specific style number format for a specific locale.\r
-     * @param inLocale  the specific locale.\r
-     * @param style     number format style\r
-     * @draft ICU 4.2\r
-     * @provisional This API might change or be removed in a future release.\r
-     */\r
-    public static NumberFormat getInstance(Locale inLocale, int style) {\r
-        return getInstance(ULocale.forLocale(inLocale), style);\r
-    }\r
-\r
-\r
-    /**\r
-     * Returns a general-purpose number format for the current default locale.\r
-     * @stable ICU 2.0\r
-     */\r
-    public final static NumberFormat getNumberInstance() {\r
-        return getInstance(ULocale.getDefault(), NUMBERSTYLE);\r
-    }\r
-\r
-    /**\r
-     * Returns a general-purpose number format for the specified locale.\r
-     * @stable ICU 2.0\r
-     */\r
-    public static NumberFormat getNumberInstance(Locale inLocale) {\r
-        return getInstance(ULocale.forLocale(inLocale), NUMBERSTYLE);\r
-    }\r
-\r
-    /**\r
-     * Returns a general-purpose number format for the specified locale.\r
-     * @stable ICU 3.2\r
-     */\r
-    public static NumberFormat getNumberInstance(ULocale inLocale) {\r
-        return getInstance(inLocale, NUMBERSTYLE);\r
-    }\r
-\r
-    /**\r
-     * Returns an integer number format for the current default locale. The\r
-     * returned number format is configured to round floating point numbers\r
-     * to the nearest integer using IEEE half-even rounding (see {@link \r
-     * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,\r
-     * and to parse only the integer part of an input string (see {@link\r
-     * #isParseIntegerOnly isParseIntegerOnly}).\r
-     *\r
-     * @return a number format for integer values\r
-     * @stable ICU 2.0\r
-     */\r
-    //Bug 4408066 [Richard/GCL]\r
-    public final static NumberFormat getIntegerInstance() {\r
-        return getInstance(ULocale.getDefault(), INTEGERSTYLE);\r
-    }\r
-\r
-    /**\r
-     * Returns an integer number format for the specified locale. The\r
-     * returned number format is configured to round floating point numbers\r
-     * to the nearest integer using IEEE half-even rounding (see {@link \r
-     * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,\r
-     * and to parse only the integer part of an input string (see {@link\r
-     * #isParseIntegerOnly isParseIntegerOnly}).\r
-     *\r
-     * @param inLocale the locale for which a number format is needed\r
-     * @return a number format for integer values\r
-     * @stable ICU 2.0\r
-     */\r
-    //Bug 4408066 [Richard/GCL]\r
-    public static NumberFormat getIntegerInstance(Locale inLocale) {\r
-        return getInstance(ULocale.forLocale(inLocale), INTEGERSTYLE);\r
-    }\r
-\r
-    /**\r
-     * Returns an integer number format for the specified locale. The\r
-     * returned number format is configured to round floating point numbers\r
-     * to the nearest integer using IEEE half-even rounding (see {@link \r
-     * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,\r
-     * and to parse only the integer part of an input string (see {@link\r
-     * #isParseIntegerOnly isParseIntegerOnly}).\r
-     *\r
-     * @param inLocale the locale for which a number format is needed\r
-     * @return a number format for integer values\r
-     * @stable ICU 3.2\r
-     */\r
-    public static NumberFormat getIntegerInstance(ULocale inLocale) {\r
-        return getInstance(inLocale, INTEGERSTYLE);\r
-    }\r
-\r
-    /**\r
-     * Returns a currency format for the current default locale.\r
-     * @return a number format for currency\r
-     * @stable ICU 2.0\r
-     */\r
-    public final static NumberFormat getCurrencyInstance() {\r
-        return getInstance(ULocale.getDefault(), CURRENCYSTYLE);\r
-    }\r
-\r
-    /**\r
-     * Returns a currency format for the specified locale.\r
-     * @return a number format for currency\r
-     * @stable ICU 2.0\r
-     */\r
-    public static NumberFormat getCurrencyInstance(Locale inLocale) {\r
-        return getInstance(ULocale.forLocale(inLocale), CURRENCYSTYLE);\r
-    }\r
-\r
-    /**\r
-     * Returns a currency format for the specified locale.\r
-     * @return a number format for currency\r
-     * @stable ICU 3.2\r
-     */\r
-    public static NumberFormat getCurrencyInstance(ULocale inLocale) {\r
-        return getInstance(inLocale, CURRENCYSTYLE);\r
-    }\r
-\r
-    /**\r
-     * Returns a percentage format for the current default locale.\r
-     * @return a number format for percents\r
-     * @stable ICU 2.0\r
-     */\r
-    public final static NumberFormat getPercentInstance() {\r
-        return getInstance(ULocale.getDefault(), PERCENTSTYLE);\r
-    }\r
-\r
-    /**\r
-     * Returns a percentage format for the specified locale.\r
-     * @return a number format for percents\r
-     * @stable ICU 2.0\r
-     */\r
-    public static NumberFormat getPercentInstance(Locale inLocale) {\r
-        return getInstance(ULocale.forLocale(inLocale), PERCENTSTYLE);\r
-    }\r
-\r
-    /**\r
-     * Returns a percentage format for the specified locale.\r
-     * @return a number format for percents\r
-     * @stable ICU 3.2\r
-     */\r
-    public static NumberFormat getPercentInstance(ULocale inLocale) {\r
-        return getInstance(inLocale, PERCENTSTYLE);\r
-    }\r
-\r
-    // [NEW]\r
-    /**\r
-     * Returns a scientific format for the current default locale.\r
-     * @return a scientific number format\r
-     * @stable ICU 2.0\r
-     */\r
-    public final static NumberFormat getScientificInstance() {\r
-        return getInstance(ULocale.getDefault(), SCIENTIFICSTYLE);\r
-    }\r
-\r
-    // [NEW]\r
-    /**\r
-     * Returns a scientific format for the specified locale.\r
-     * @return a scientific number format\r
-     * @stable ICU 2.0\r
-     */\r
-    public static NumberFormat getScientificInstance(Locale inLocale) {\r
-        return getInstance(ULocale.forLocale(inLocale), SCIENTIFICSTYLE);\r
-    }\r
-\r
-    // [NEW]\r
-    /**\r
-     * Returns a scientific format for the specified locale.\r
-     * @return a scientific number format\r
-     * @stable ICU 3.2\r
-     */\r
-    public static NumberFormat getScientificInstance(ULocale inLocale) {\r
-        return getInstance(inLocale, SCIENTIFICSTYLE);\r
-    }\r
-\r
-    // ===== Factory stuff =====\r
-    /**\r
-     * A NumberFormatFactory is used to register new number formats.  The factory\r
-     * should be able to create any of the predefined formats for each locale it\r
-     * supports.  When registered, the locales it supports extend or override the\r
-     * locales already supported by ICU.\r
-     * <p><b>Note:</b> as of ICU4J 3.2, the default API for NumberFormatFactory uses\r
-     * ULocale instead of Locale.  Instead of overriding createFormat(Locale, int),\r
-     * new implementations should override createFactory(ULocale, int).  Note that\r
-     * one of these two methods <b>MUST</b> be overridden or else an infinite\r
-     * loop will occur.\r
-     *\r
-     * @stable ICU 2.6\r
-     */\r
-    public static abstract class NumberFormatFactory {\r
-        /**\r
-         * Value passed to format requesting a default number format.\r
-         * @stable ICU 2.6\r
-         */\r
-        public static final int FORMAT_NUMBER = NUMBERSTYLE;\r
-\r
-        /**\r
-         * Value passed to format requesting a currency format.\r
-         * @stable ICU 2.6\r
-         */\r
-        public static final int FORMAT_CURRENCY = CURRENCYSTYLE;\r
-\r
-        /**\r
-         * Value passed to format requesting a percent format.\r
-         * @stable ICU 2.6\r
-         */\r
-        public static final int FORMAT_PERCENT = PERCENTSTYLE;\r
-\r
-        /**\r
-         * Value passed to format requesting a scientific format.\r
-         * @stable ICU 2.6\r
-         */\r
-        public static final int FORMAT_SCIENTIFIC = SCIENTIFICSTYLE;\r
-\r
-        /**\r
-         * Value passed to format requesting an integer format.\r
-         * @stable ICU 2.6\r
-         */\r
-        public static final int FORMAT_INTEGER = INTEGERSTYLE;\r
-\r
-        /**\r
-         * Returns true if this factory is visible.  Default is true.\r
-         * If not visible, the locales supported by this factory will not\r
-         * be listed by getAvailableLocales.  This value must not change.\r
-         * @return true if the factory is visible.\r
-         * @stable ICU 2.6\r
-         */\r
-        ///CLOVER:OFF\r
-        public boolean visible() {\r
-            return true;\r
-        }\r
-        ///CLOVER:ON\r
-\r
-        /**\r
-         * Returns an immutable collection of the locale names directly \r
-         * supported by this factory.\r
-         * @return the supported locale names.\r
-         * @stable ICU 2.6\r
-         */\r
-         public abstract Set getSupportedLocaleNames();\r
-\r
-        /**\r
-         * Returns a number format of the appropriate type.  If the locale\r
-         * is not supported, return null.  If the locale is supported, but\r
-         * the type is not provided by this service, return null.  Otherwise\r
-         * return an appropriate instance of NumberFormat.\r
-         * <b>Note:</b> as of ICU4J 3.2, implementations should override\r
-         * this method instead of createFormat(Locale, int).\r
-         * @param loc the locale for which to create the format\r
-         * @param formatType the type of format\r
-         * @return the NumberFormat, or null.\r
-         * @stable ICU 3.2\r
-         */\r
-        public NumberFormat createFormat(ULocale loc, int formatType) {\r
-            return createFormat(loc.toLocale(), formatType);\r
-        }\r
-\r
-        /**\r
-         * Returns a number format of the appropriate type.  If the locale\r
-         * is not supported, return null.  If the locale is supported, but\r
-         * the type is not provided by this service, return null.  Otherwise\r
-         * return an appropriate instance of NumberFormat.\r
-         * <b>Note:</b> as of ICU4J 3.2, createFormat(ULocale, int) should be\r
-         * overridden instead of this method.  This method is no longer \r
-         * abstract and delegates to that method.\r
-         * @param loc the locale for which to create the format\r
-         * @param formatType the type of format\r
-         * @return the NumberFormat, or null.\r
-         * @stable ICU 2.6\r
-         */\r
-        public NumberFormat createFormat(Locale loc, int formatType) {\r
-            return createFormat(ULocale.forLocale(loc), formatType);\r
-        }\r
-\r
-        /**\r
-         * @stable ICU 2.6\r
-         */\r
-        protected NumberFormatFactory() {\r
-        }\r
-    }\r
-\r
-    /**\r
-     * A NumberFormatFactory that supports a single locale.  It can be visible or invisible.\r
-     * @stable ICU 2.6\r
-     */\r
-    public static abstract class SimpleNumberFormatFactory extends NumberFormatFactory {\r
-        final Set localeNames;\r
-        final boolean visible;\r
-\r
-        /**\r
-         * Constructs a SimpleNumberFormatFactory with the given locale.\r
-         * @stable ICU 2.6\r
-         */\r
-        public SimpleNumberFormatFactory(Locale locale) {\r
-            this(locale, true);\r
-        }\r
-        \r
-        /**\r
-         * Constructs a SimpleNumberFormatFactory with the given locale and the\r
-         * visibility.\r
-         * @stable ICU 2.6\r
-         */\r
-        public SimpleNumberFormatFactory(Locale locale, boolean visible) {\r
-            localeNames = Collections.singleton(ULocale.forLocale(locale).getBaseName());\r
-            this.visible = visible;\r
-        }\r
-\r
-        /**\r
-         * Constructs a SimpleNumberFormatFactory with the given locale.\r
-         * @stable ICU 3.2\r
-         */\r
-        public SimpleNumberFormatFactory(ULocale locale) {\r
-            this(locale, true);\r
-        }\r
-        \r
-        /**\r
-         * Constructs a SimpleNumberFormatFactory with the given locale and the\r
-         * visibility.\r
-         * @stable ICU 3.2\r
-         */\r
-        public SimpleNumberFormatFactory(ULocale locale, boolean visible) {\r
-            localeNames = Collections.singleton(locale.getBaseName());\r
-            this.visible = visible;\r
-        }\r
-\r
-        /**\r
-         * {@inheritDoc}\r
-         * @stable ICU 2.6\r
-         */\r
-        public final boolean visible() {\r
-            return visible;\r
-        }\r
-\r
-        /**\r
-         * {@inheritDoc}\r
-         * @stable ICU 2.6\r
-         */\r
-        public final Set getSupportedLocaleNames() {\r
-            return localeNames;\r
-        }\r
-    }\r
-\r
-    // shim so we can build without service code\r
-    static abstract class NumberFormatShim {\r
-        abstract Locale[] getAvailableLocales();\r
-        abstract ULocale[] getAvailableULocales();\r
-        abstract Object registerFactory(NumberFormatFactory f);\r
-        abstract boolean unregister(Object k);\r
-        abstract NumberFormat createInstance(ULocale l, int k);\r
-    }\r
-\r
-    private static NumberFormatShim shim;\r
-    private static NumberFormatShim getShim() {\r
-        // Note: this instantiation is safe on loose-memory-model configurations\r
-        // despite lack of synchronization, since the shim instance has no state--\r
-        // it's all in the class init.  The worst problem is we might instantiate\r
-        // two shim instances, but they'll share the same state so that's ok.\r
-        if (shim == null) {\r
-            try {\r
-                Class cls = Class.forName("com.ibm.icu.text.NumberFormatServiceShim");\r
-                shim = (NumberFormatShim)cls.newInstance();\r
-            }\r
-            catch (MissingResourceException e){\r
-                throw e;\r
-            }\r
-            catch (Exception e) {\r
-                ///CLOVER:OFF\r
-               // e.printStackTrace();\r
-                throw new RuntimeException(e.getMessage());\r
-                ///CLOVER:ON\r
-            }\r
-        }\r
-        return shim;\r
-    }\r
-\r
-    /**\r
-     * Get the list of Locales for which NumberFormats are available.\r
-     * @return the available locales\r
-     * @stable ICU 2.0\r
-     */\r
-    public static Locale[] getAvailableLocales() {\r
-        if (shim == null) {\r
-            return ICUResourceBundle.getAvailableLocales(ICUResourceBundle.ICU_BASE_NAME);\r
-        }\r
-        return getShim().getAvailableLocales();\r
-    }\r
-\r
-    /**\r
-     * Get the list of Locales for which NumberFormats are available.\r
-     * @return the available locales\r
-     * @draft ICU 3.2 (retain)\r
-     * @provisional This API might change or be removed in a future release.\r
-     */\r
-    public static ULocale[] getAvailableULocales() {\r
-        if (shim == null) {\r
-            return ICUResourceBundle.getAvailableULocales(ICUResourceBundle.ICU_BASE_NAME);\r
-        }\r
-        return getShim().getAvailableULocales();\r
-    }\r
-\r
-    /**\r
-     * Registers a new NumberFormatFactory.  The factory is adopted by\r
-     * the service and must not be modified.  The returned object is a\r
-     * key that can be used to unregister this factory.\r
-     * @param factory the factory to register\r
-     * @return a key with which to unregister the factory\r
-     * @stable ICU 2.6 \r
-     */\r
-    public static Object registerFactory(NumberFormatFactory factory) {\r
-        if (factory == null) {\r
-            throw new IllegalArgumentException("factory must not be null");\r
-        }\r
-        return getShim().registerFactory(factory);\r
-    }\r
-\r
-    /**\r
-     * Unregister the factory or instance associated with this key (obtained from\r
-     * registerInstance or registerFactory).\r
-     * @param registryKey a key obtained from registerFactory\r
-     * @return true if the object was successfully unregistered\r
-     * @stable ICU 2.6\r
-     */\r
-    public static boolean unregister(Object registryKey) {\r
-        if (registryKey == null) {\r
-            throw new IllegalArgumentException("registryKey must not be null");\r
-        }\r
-\r
-        if (shim == null) {\r
-            return false;\r
-        }\r
-\r
-        return shim.unregister(registryKey);\r
-    }\r
-\r
-    // ===== End of factory stuff =====\r
-\r
-    /**\r
-     * Overrides hashCode\r
-     * @stable ICU 2.0\r
-     */\r
-    public int hashCode() {\r
-        return maximumIntegerDigits * 37 + maxFractionDigits;\r
-        // just enough fields for a reasonable distribution\r
-    }\r
-\r
-    /**\r
-     * Overrides equals.  Two NumberFormats are equal if they are of the same class\r
-     * and the settings (groupingUsed, parseIntegerOnly, maximumIntegerDigits, etc.\r
-     * are equal.\r
-     * @param obj the object to compare against\r
-     * @return true if the object is equal to this.\r
-     * @stable ICU 2.0\r
-     */\r
-    public boolean equals(Object obj) {\r
-        if (obj == null) return false;\r
-        if (this == obj)\r
-            return true;\r
-        if (getClass() != obj.getClass())\r
-            return false;\r
-        NumberFormat other = (NumberFormat) obj;\r
-        return maximumIntegerDigits == other.maximumIntegerDigits\r
-            && minimumIntegerDigits == other.minimumIntegerDigits\r
-            && maximumFractionDigits == other.maximumFractionDigits\r
-            && minimumFractionDigits == other.minimumFractionDigits\r
-            && groupingUsed == other.groupingUsed\r
-            && parseIntegerOnly == other.parseIntegerOnly\r
-            && parseStrict == other.parseStrict;\r
-    }\r
-\r
-    /**\r
-     * Overrides Cloneable.\r
-     * @stable ICU 2.0\r
-     */\r
-    public Object clone()\r
-    {\r
-        NumberFormat other = (NumberFormat) super.clone();\r
-        return other;\r
-    }\r
-\r
-    /**\r
-     * Returns true if grouping is used in this format. For example, in the\r
-     * en_US locale, with grouping on, the number 1234567 will be formatted\r
-     * as "1,234,567". The grouping separator as well as the size of each group\r
-     * is locale-dependent and is determined by subclasses of NumberFormat.\r
-     * Grouping affects both parsing and formatting.\r
-     * @return true if grouping is used\r
-     * @see #setGroupingUsed\r
-     * @stable ICU 2.0\r
-     */\r
-    public boolean isGroupingUsed() {\r
-        return groupingUsed;\r
-    }\r
-\r
-    /**\r
-     * Sets whether or not grouping will be used in this format.  Grouping\r
-     * affects both parsing and formatting.\r
-     * @see #isGroupingUsed\r
-     * @param newValue true to use grouping.\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setGroupingUsed(boolean newValue) {\r
-        groupingUsed = newValue;\r
-    }\r
-\r
-    /**\r
-     * Returns the maximum number of digits allowed in the integer portion of a\r
-     * number.  The default value is 40, which subclasses can override.\r
-     * When formatting, the exact behavior when this value is exceeded is\r
-     * subclass-specific.  When parsing, this has no effect.\r
-     * @return the maximum number of integer digits\r
-     * @see #setMaximumIntegerDigits\r
-     * @stable ICU 2.0\r
-     */\r
-    public int getMaximumIntegerDigits() {\r
-        return maximumIntegerDigits;\r
-    }\r
-\r
-    /**\r
-     * Sets the maximum number of digits allowed in the integer portion of a\r
-     * number. This must be >= minimumIntegerDigits.  If the\r
-     * new value for maximumIntegerDigits is less than the current value\r
-     * of minimumIntegerDigits, then minimumIntegerDigits will also be set to\r
-     * the new value.\r
-     * @param newValue the maximum number of integer digits to be shown; if\r
-     * less than zero, then zero is used.  Subclasses might enforce an\r
-     * upper limit to this value appropriate to the numeric type being formatted.\r
-     * @see #getMaximumIntegerDigits\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setMaximumIntegerDigits(int newValue) {\r
-        maximumIntegerDigits = Math.max(0,newValue);\r
-        if (minimumIntegerDigits > maximumIntegerDigits)\r
-            minimumIntegerDigits = maximumIntegerDigits;\r
-    }\r
-\r
-    /**\r
-     * Returns the minimum number of digits allowed in the integer portion of a\r
-     * number.  The default value is 1, which subclasses can override.\r
-     * When formatting, if this value is not reached, numbers are padded on the\r
-     * left with the locale-specific '0' character to ensure at least this\r
-     * number of integer digits.  When parsing, this has no effect.\r
-     * @return the minimum number of integer digits\r
-     * @see #setMinimumIntegerDigits\r
-     * @stable ICU 2.0\r
-     */\r
-    public int getMinimumIntegerDigits() {\r
-        return minimumIntegerDigits;\r
-    }\r
-\r
-    /**\r
-     * Sets the minimum number of digits allowed in the integer portion of a\r
-     * number.  This must be <= maximumIntegerDigits.  If the\r
-     * new value for minimumIntegerDigits is more than the current value\r
-     * of maximumIntegerDigits, then maximumIntegerDigits will also be set to\r
-     * the new value.\r
-     * @param newValue the minimum number of integer digits to be shown; if\r
-     * less than zero, then zero is used. Subclasses might enforce an\r
-     * upper limit to this value appropriate to the numeric type being formatted.\r
-     * @see #getMinimumIntegerDigits\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setMinimumIntegerDigits(int newValue) {\r
-        minimumIntegerDigits = Math.max(0,newValue);\r
-        if (minimumIntegerDigits > maximumIntegerDigits)\r
-            maximumIntegerDigits = minimumIntegerDigits;\r
-    }\r
-\r
-    /**\r
-     * Returns the maximum number of digits allowed in the fraction\r
-     * portion of a number.  The default value is 3, which subclasses\r
-     * can override.  When formatting, the exact behavior when this\r
-     * value is exceeded is subclass-specific.  When parsing, this has \r
-     * no effect.\r
-     * @return the maximum number of fraction digits\r
-     * @see #setMaximumFractionDigits\r
-     * @stable ICU 2.0 \r
-     */\r
-    public int getMaximumFractionDigits() {\r
-        return maximumFractionDigits;\r
-    }\r
-\r
-    /**\r
-     * Sets the maximum number of digits allowed in the fraction portion of a\r
-     * number. This must be >= minimumFractionDigits.  If the\r
-     * new value for maximumFractionDigits is less than the current value\r
-     * of minimumFractionDigits, then minimumFractionDigits will also be set to\r
-     * the new value.\r
-     * @param newValue the maximum number of fraction digits to be shown; if\r
-     * less than zero, then zero is used. The concrete subclass may enforce an\r
-     * upper limit to this value appropriate to the numeric type being formatted.\r
-     * @see #getMaximumFractionDigits\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setMaximumFractionDigits(int newValue) {\r
-        maximumFractionDigits = Math.max(0,newValue);\r
-        if (maximumFractionDigits < minimumFractionDigits)\r
-            minimumFractionDigits = maximumFractionDigits;\r
-    }\r
-\r
-    /**\r
-     * Returns the minimum number of digits allowed in the fraction portion of a\r
-     * number.  The default value is 0, which subclasses can override.\r
-     * When formatting, if this value is not reached, numbers are padded on\r
-     * the right with the locale-specific '0' character to ensure at least\r
-     * this number of fraction digits.  When parsing, this has no effect.\r
-     * @return the minimum number of fraction digits\r
-     * @see #setMinimumFractionDigits\r
-     * @stable ICU 2.0\r
-     */\r
-    public int getMinimumFractionDigits() {\r
-        return minimumFractionDigits;\r
-    }\r
-\r
-    /**\r
-     * Sets the minimum number of digits allowed in the fraction portion of a\r
-     * number.  This must be <= maximumFractionDigits.  If the\r
-     * new value for minimumFractionDigits exceeds the current value\r
-     * of maximumFractionDigits, then maximumFractionDigits will also be set to\r
-     * the new value.\r
-     * @param newValue the minimum number of fraction digits to be shown; if\r
-     * less than zero, then zero is used.  Subclasses might enforce an\r
-     * upper limit to this value appropriate to the numeric type being formatted.\r
-     * @see #getMinimumFractionDigits\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setMinimumFractionDigits(int newValue) {\r
-        minimumFractionDigits = Math.max(0,newValue);\r
-        if (maximumFractionDigits < minimumFractionDigits)\r
-            maximumFractionDigits = minimumFractionDigits;\r
-    }\r
-\r
-    /**\r
-     * Sets the <tt>Currency</tt> object used to display currency\r
-     * amounts.  This takes effect immediately, if this format is a\r
-     * currency format.  If this format is not a currency format, then\r
-     * the currency object is used if and when this object becomes a\r
-     * currency format.\r
-     * @param theCurrency new currency object to use.  May be null for\r
-     * some subclasses.\r
-     * @stable ICU 2.6\r
-     */\r
-    public void setCurrency(Currency theCurrency) {\r
-        currency = theCurrency;\r
-    }\r
-\r
-    /**\r
-     * Gets the <tt>Currency</tt> object used to display currency\r
-     * amounts.  This may be null.\r
-     * @stable ICU 2.6\r
-     */\r
-    public Currency getCurrency() {\r
-        return currency;\r
-    }\r
-    \r
-    /**\r
-     * Returns the currency in effect for this formatter.  Subclasses\r
-     * should override this method as needed.  Unlike getCurrency(),\r
-     * this method should never return null.\r
-     * @return a non-null Currency\r
-     * @internal\r
-     * @deprecated This API is ICU internal only.\r
-     */\r
-    protected Currency getEffectiveCurrency() {\r
-        Currency c = getCurrency();\r
-        if (c == null) {\r
-            ULocale uloc = getLocale(ULocale.VALID_LOCALE);\r
-            if (uloc == null) {\r
-                uloc = ULocale.getDefault();\r
-            }\r
-            c = Currency.getInstance(uloc);\r
-        }\r
-        return c;\r
-    }\r
-\r
-    /**\r
-     * Get the rounding mode used in this NumberFormat.  The default implementation of\r
-     * tis method in NumberFormat always throws <code>UnsupportedOperationException</code>.\r
-     * @return A rounding mode, between <code>BigDecimal.ROUND_UP</code>\r
-     * and <code>BigDecimal.ROUND_UNNECESSARY</code>.\r
-     * @see #setRoundingMode(int)\r
-     * @stable ICU 4.0\r
-     */\r
-    public int getRoundingMode() {\r
-        throw new UnsupportedOperationException("getRoundingMode must be implemented by the subclass implementation.");\r
-    }\r
-\r
-    /**\r
-     * Set the rounding mode used in this NumberFormat.  The default implementation of\r
-     * tis method in NumberFormat always throws <code>UnsupportedOperationException</code>.\r
-     * @param roundingMode A rounding mode, between\r
-     * <code>BigDecimal.ROUND_UP</code> and\r
-     * <code>BigDecimal.ROUND_UNNECESSARY</code>.\r
-     * @see #getRoundingMode()\r
-     * @stable ICU 4.0\r
-     */\r
-    public void setRoundingMode(int roundingMode) {\r
-        throw new UnsupportedOperationException("setRoundingMode must be implemented by the subclass implementation.");\r
-    }\r
-\r
-\r
-    /**\r
-     * Returns a specific style number format for a specific locale.\r
-     * @param desiredLocale  the specific locale.\r
-     * @param choice         number format style\r
-     * @throws IllegalArgumentException  if choice is not one of\r
-     *                                   NUMBERSTYLE, CURRENCYSTYLE, \r
-     *                                   PERCENTSTYLE, SCIENTIFICSTYLE, \r
-     *                                   INTEGERSTYLE, \r
-     *                                   ISOCURRENCYSTYLE, PLURALCURRENCYSTYLE,\r
-     * @draft ICU 4.2\r
-     * @provisional This API might change or be removed in a future release.\r
-     */\r
-    public static NumberFormat getInstance(ULocale desiredLocale, int choice) {\r
-        if (choice < NUMBERSTYLE || choice > PLURALCURRENCYSTYLE) {\r
-            throw new IllegalArgumentException("choice should be from NUMBERSTYLE to PLURALCURRENCYSTYLE");\r
-        }       \r
-//          if (shim == null) {\r
-//              return createInstance(desiredLocale, choice);\r
-//          } else {\r
-//              // TODO: shims must call setLocale() on object they create\r
-//              return getShim().createInstance(desiredLocale, choice);\r
-//          }\r
-        return getShim().createInstance(desiredLocale, choice);\r
-    }\r
-\r
-    // =======================privates===============================\r
-    // Hook for service\r
-    // [NEW]\r
-    static NumberFormat createInstance(ULocale desiredLocale, int choice) {\r
-        // If the choice is PLURALCURRENCYSTYLE, the pattern is not a single\r
-        // pattern, it is a pattern set, so we do not need to get them here.\r
-        // If the choice is ISOCURRENCYSTYLE, the pattern is the currrency\r
-        // pattern in the locale but by replacing the single currency sign \r
-        // with double currency sign.\r
-        String pattern = getPattern(desiredLocale, choice);\r
-        DecimalFormatSymbols symbols = new DecimalFormatSymbols(desiredLocale);\r
-        \r
-        // Here we assume that the locale passed in is in the canonical\r
-        // form, e.g: pt_PT_@currency=PTE not pt_PT_PREEURO\r
-        // This style wont work for currency plural format.\r
-        // For currency plural format, the pattern is get from \r
-        // the locale (from CurrencyUnitPatterns) without override.\r
-        if(choice == CURRENCYSTYLE || choice == ISOCURRENCYSTYLE){\r
-            String temp = symbols.getCurrencyPattern();\r
-            if(temp!=null){\r
-                pattern = temp;\r
-            }\r
-        }\r
-\r
-        // replace single currency sign in the pattern with double currency sign\r
-        // if the choice is ISOCURRENCYSTYLE.\r
-        if (choice == ISOCURRENCYSTYLE) {\r
-            pattern = Utility.replace(pattern, "\u00A4", doubleCurrencyStr);\r
-        }\r
-\r
-        NumberingSystem ns = NumberingSystem.getInstance(desiredLocale);\r
-        if ( ns == null ) {\r
-            return null;\r
-        }\r
-\r
-        NumberFormat format;\r
-\r
-        if ( ns != null && ns.isAlgorithmic()) {\r
-            String nsDesc;\r
-            String nsRuleSetGroup;\r
-            String nsRuleSetName;\r
-            ULocale nsLoc;\r
-            int desiredRulesType = RuleBasedNumberFormat.NUMBERING_SYSTEM;\r
-\r
-            nsDesc = ns.getDescription();\r
-            int firstSlash = nsDesc.indexOf("/");\r
-            int lastSlash = nsDesc.lastIndexOf("/");\r
-\r
-            if ( lastSlash > firstSlash ) {\r
-               String nsLocID = nsDesc.substring(0,firstSlash);\r
-               nsRuleSetGroup = nsDesc.substring(firstSlash+1,lastSlash);\r
-               nsRuleSetName = nsDesc.substring(lastSlash+1);\r
-\r
-               nsLoc = new ULocale(nsLocID);\r
-               if ( nsRuleSetGroup.equals("SpelloutRules")) {\r
-                   desiredRulesType = RuleBasedNumberFormat.SPELLOUT;\r
-               }\r
-            } else {\r
-                nsLoc = desiredLocale;\r
-                nsRuleSetName = nsDesc;\r
-            }\r
-\r
-            RuleBasedNumberFormat r = new RuleBasedNumberFormat(nsLoc,desiredRulesType);\r
-            r.setDefaultRuleSet(nsRuleSetName);\r
-            format = r;\r
-        } else {\r
-            DecimalFormat f = new DecimalFormat(pattern, symbols, choice);\r
-            // System.out.println("loc: " + desiredLocale + " choice: " + choice + " pat: " + pattern + " sym: " + symbols + " result: " + format);\r
-                                 \r
-            /*Bug 4408066\r
-             Add codes for the new method getIntegerInstance() [Richard/GCL]\r
-            */\r
-            // TODO: revisit this -- this is almost certainly not the way we want\r
-            // to do this.  aliu 1/6/2004\r
-            if (choice == INTEGERSTYLE) {\r
-                f.setMaximumFractionDigits(0);\r
-                f.setDecimalSeparatorAlwaysShown(false);\r
-                f.setParseIntegerOnly(true);\r
-            }\r
-            format = f;\r
-       } \r
-        // TODO: the actual locale of the *pattern* may differ from that\r
-        // for the *symbols*.  For now, we use the data for the symbols.\r
-        // Revisit this.\r
-        ULocale valid = symbols.getLocale(ULocale.VALID_LOCALE);\r
-        ULocale actual = symbols.getLocale(ULocale.ACTUAL_LOCALE);\r
-        format.setLocale(valid, actual);\r
-        \r
-        return format;\r
-    }\r
-\r
-    /**\r
-     * Returns the pattern for the provided locale and choice.\r
-     * @param forLocale the locale of the data.\r
-     * @param choice the pattern format.\r
-     * @return the pattern\r
-     * @deprecated ICU 3.4 subclassers should override getPattern(ULocale, int) instead of this method.\r
-     */\r
-    protected static String getPattern(Locale forLocale, int choice) {\r
-        return getPattern(ULocale.forLocale(forLocale), choice);\r
-    }\r
-\r
-    /**\r
-     * Returns the pattern for the provided locale and choice.\r
-     * @param forLocale the locale of the data.\r
-     * @param choice the pattern format.\r
-     * @return the pattern\r
-     * @stable ICU 3.2\r
-     */\r
-    protected static String getPattern(ULocale forLocale, int choice) {\r
-\r
-        /* The following code takes care of a few cases where the\r
-         * resource data in the underlying JDK lags the new features\r
-         * we have added to ICU4J: scientific notation, rounding, and\r
-         * secondary grouping.\r
-         *\r
-         * We detect these cases here and return various hard-coded\r
-         * resource data.  This is the simplest solution for now, but\r
-         * it is not a good long-term mechanism.\r
-         * \r
-         * We should replace this code with a data-driven mechanism\r
-         * that reads the bundle com.ibm.icu.impl.data.LocaleElements\r
-         * and parses an exception table that overrides the standard\r
-         * data at java.text.resource.LocaleElements*.java.\r
-         * Alternatively, we should create our own copy of the\r
-         * resource data, and use that exclusively.\r
-         */\r
-\r
-        // TEMPORARY, until we get scientific patterns into the main\r
-        // resources:  Retrieve scientific patterns from our resources.\r
-        if (choice == SCIENTIFICSTYLE) {\r
-            // Temporarily hard code; retrieve from resource later\r
-            /*For ICU compatibility [Richard/GCL]*/\r
-            return "#E0";\r
-            // return NumberFormat.getBaseStringArray("NumberPatterns")[SCIENTIFICSTYLE];\r
-        }\r
-        // TEMPORARY: Use rounding for Swiss currency\r
-        //if (choice == CURRENCYSTYLE &&\r
-        //    forLocale.getCountry().equals("CH")) {\r
-        //    return "'Fr. '#,##0.05;'Fr.-'#,##0.05";\r
-        //}\r
-        // TEMPORARY: Special case IN number format\r
-        //if (choice == NUMBERSTYLE &&\r
-        //    forLocale.getCountry().equals("IN")) {\r
-        //    return "#,##,##0.###";\r
-        //}\r
-\r
-        // {dlf}\r
-        ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.\r
-            getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, forLocale);\r
-        String[] numberPatterns = rb.getStringArray("NumberPatterns");\r
-\r
-        /* {dlf}\r
-        // Try the cache first\r
-        String[] numberPatterns = (String[]) cachedLocaleData.get(forLocale);\r
-        if (numberPatterns == null) {\r
-            OverlayBundle resource = new OverlayBundle(new String[]\r
-                { "com.ibm.icu.impl.data.LocaleElements", RESOURCE_BASE }, forLocale);\r
-            numberPatterns = resource.getStringArray("NumberPatterns");\r
-            // Update the cache\r
-            cachedLocaleData.put(forLocale, numberPatterns); \r
-        }\r
-        */\r
-\r
-        /*Bug 4408066\r
-         Add codes for the new method getIntegerInstance() [Richard/GCL]\r
-        */\r
-        /* for ISOCURRENCYSTYLE and PLURALCURRENCYSTYLE,\r
-         * the pattern is the same as the pattern of CURRENCYSTYLE\r
-         * but by replacing the single currency sign with\r
-         * double currency sign or triple currency sign.\r
-         */\r
-        int entry = (choice == INTEGERSTYLE) ? NUMBERSTYLE : \r
-                ((choice == ISOCURRENCYSTYLE || choice == PLURALCURRENCYSTYLE)?\r
-                CURRENCYSTYLE : choice); //[Richard/GCL]\r
-        return numberPatterns[entry]; //[Richard/GCL]\r
-    }\r
-\r
-    /**\r
-     * First, read in the default serializable data.\r
-     *\r
-     * Then, if <code>serialVersionOnStream</code> is less than 1, indicating that\r
-     * the stream was written by JDK 1.1,\r
-     * set the <code>int</code> fields such as <code>maximumIntegerDigits</code>\r
-     * to be equal to the <code>byte</code> fields such as <code>maxIntegerDigits</code>,\r
-     * since the <code>int</code> fields were not present in JDK 1.1.\r
-     * Finally, set serialVersionOnStream back to the maximum allowed value so that\r
-     * default serialization will work properly if this object is streamed out again.\r
-     */\r
-    private void readObject(ObjectInputStream stream)\r
-         throws IOException, ClassNotFoundException\r
-    {\r
-        stream.defaultReadObject();\r
-        ///CLOVER:OFF\r
-        // we don't have serialization data for this format\r
-        if (serialVersionOnStream < 1) {\r
-            // Didn't have additional int fields, reassign to use them.\r
-            maximumIntegerDigits = maxIntegerDigits;\r
-            minimumIntegerDigits = minIntegerDigits;\r
-            maximumFractionDigits = maxFractionDigits;\r
-            minimumFractionDigits = minFractionDigits;\r
-        }\r
-        ///CLOVER:ON\r
-        /*Bug 4185761\r
-          Validate the min and max fields [Richard/GCL]\r
-        */\r
-        if (minimumIntegerDigits > maximumIntegerDigits ||\r
-            minimumFractionDigits > maximumFractionDigits ||\r
-            minimumIntegerDigits < 0 || minimumFractionDigits < 0) {\r
-            throw new InvalidObjectException("Digit count range invalid");\r
-        }\r
-        serialVersionOnStream = currentSerialVersion;\r
-    }\r
-\r
-    /**\r
-     * Write out the default serializable data, after first setting\r
-     * the <code>byte</code> fields such as <code>maxIntegerDigits</code> to be\r
-     * equal to the <code>int</code> fields such as <code>maximumIntegerDigits</code>\r
-     * (or to <code>Byte.MAX_VALUE</code>, whichever is smaller), for compatibility\r
-     * with the JDK 1.1 version of the stream format.\r
-     */\r
-    private void writeObject(ObjectOutputStream stream)\r
-         throws IOException\r
-    {\r
-        maxIntegerDigits = (maximumIntegerDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :\r
-            (byte)maximumIntegerDigits;\r
-        minIntegerDigits = (minimumIntegerDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :\r
-            (byte)minimumIntegerDigits;\r
-        maxFractionDigits = (maximumFractionDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :\r
-            (byte)maximumFractionDigits;\r
-        minFractionDigits = (minimumFractionDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :\r
-            (byte)minimumFractionDigits;\r
-        stream.defaultWriteObject();\r
-    }\r
-\r
-// Unused -- Alan 2003-05\r
-//    /**\r
-//     * Cache to hold the NumberPatterns of a Locale.\r
-//     */\r
-//    private static final Hashtable cachedLocaleData = new Hashtable(3);\r
-\r
-      private static final char[] doubleCurrencySign = {0xA4, 0xA4};\r
-      private static final String doubleCurrencyStr = new String(doubleCurrencySign);\r
-\r
-    /*Bug 4408066\r
-      Add Field for the new method getIntegerInstance() [Richard/GCL]\r
-    */\r
-\r
-    /**\r
-     * True if the the grouping (i.e. thousands) separator is used when\r
-     * formatting and parsing numbers.\r
-     *\r
-     * @serial\r
-     * @see #isGroupingUsed\r
-     */\r
-    private boolean groupingUsed = true;\r
-\r
-    /**\r
-     * The maximum number of digits allowed in the integer portion of a\r
-     * number.  <code>maxIntegerDigits</code> must be greater than or equal to\r
-     * <code>minIntegerDigits</code>.\r
-     * <p>\r
-     * <strong>Note:</strong> This field exists only for serialization\r
-     * compatibility with JDK 1.1.  In JDK 1.2 and higher, the new\r
-     * <code>int</code> field <code>maximumIntegerDigits</code> is used instead.\r
-     * When writing to a stream, <code>maxIntegerDigits</code> is set to\r
-     * <code>maximumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,\r
-     * whichever is smaller.  When reading from a stream, this field is used\r
-     * only if <code>serialVersionOnStream</code> is less than 1. \r
-     *\r
-     * @serial\r
-     * @see #getMaximumIntegerDigits\r
-     */\r
-    private byte    maxIntegerDigits = 40;\r
-\r
-    /**\r
-     * The minimum number of digits allowed in the integer portion of a\r
-     * number.  <code>minimumIntegerDigits</code> must be less than or equal to\r
-     * <code>maximumIntegerDigits</code>.\r
-     * <p>\r
-     * <strong>Note:</strong> This field exists only for serialization\r
-     * compatibility with JDK 1.1.  In JDK 1.2 and higher, the new\r
-     * <code>int</code> field <code>minimumIntegerDigits</code> is used instead.\r
-     * When writing to a stream, <code>minIntegerDigits</code> is set to\r
-     * <code>minimumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,\r
-     * whichever is smaller.  When reading from a stream, this field is used\r
-     * only if <code>serialVersionOnStream</code> is less than 1. \r
-     *\r
-     * @serial\r
-     * @see #getMinimumIntegerDigits\r
-     */\r
-    private byte    minIntegerDigits = 1;\r
-\r
-    /**\r
-     * The maximum number of digits allowed in the fractional portion of a\r
-     * number.  <code>maximumFractionDigits</code> must be greater than or equal to\r
-     * <code>minimumFractionDigits</code>.\r
-     * <p>\r
-     * <strong>Note:</strong> This field exists only for serialization\r
-     * compatibility with JDK 1.1.  In JDK 1.2 and higher, the new\r
-     * <code>int</code> field <code>maximumFractionDigits</code> is used instead.\r
-     * When writing to a stream, <code>maxFractionDigits</code> is set to\r
-     * <code>maximumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,\r
-     * whichever is smaller.  When reading from a stream, this field is used\r
-     * only if <code>serialVersionOnStream</code> is less than 1. \r
-     *\r
-     * @serial\r
-     * @see #getMaximumFractionDigits\r
-     */\r
-    private byte    maxFractionDigits = 3;    // invariant, >= minFractionDigits\r
-\r
-    /**\r
-     * The minimum number of digits allowed in the fractional portion of a\r
-     * number.  <code>minimumFractionDigits</code> must be less than or equal to\r
-     * <code>maximumFractionDigits</code>.\r
-     * <p>\r
-     * <strong>Note:</strong> This field exists only for serialization\r
-     * compatibility with JDK 1.1.  In JDK 1.2 and higher, the new\r
-     * <code>int</code> field <code>minimumFractionDigits</code> is used instead.\r
-     * When writing to a stream, <code>minFractionDigits</code> is set to\r
-     * <code>minimumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,\r
-     * whichever is smaller.  When reading from a stream, this field is used\r
-     * only if <code>serialVersionOnStream</code> is less than 1. \r
-     *\r
-     * @serial\r
-     * @see #getMinimumFractionDigits\r
-     */\r
-    private byte    minFractionDigits = 0;\r
-\r
-    /**\r
-     * True if this format will parse numbers as integers only.\r
-     *\r
-     * @serial\r
-     * @see #isParseIntegerOnly\r
-     */\r
-    private boolean parseIntegerOnly = false;\r
-\r
-    // new fields for 1.2.  byte is too small for integer digits.\r
-\r
-    /**\r
-     * The maximum number of digits allowed in the integer portion of a\r
-     * number.  <code>maximumIntegerDigits</code> must be greater than or equal to\r
-     * <code>minimumIntegerDigits</code>.\r
-     *\r
-     * @serial\r
-     * @see #getMaximumIntegerDigits\r
-     */\r
-    private int    maximumIntegerDigits = 40;\r
-\r
-    /**\r
-     * The minimum number of digits allowed in the integer portion of a\r
-     * number.  <code>minimumIntegerDigits</code> must be less than or equal to\r
-     * <code>maximumIntegerDigits</code>.\r
-     *\r
-     * @serial\r
-     * @see #getMinimumIntegerDigits\r
-     */\r
-    private int    minimumIntegerDigits = 1;\r
-\r
-    /**\r
-     * The maximum number of digits allowed in the fractional portion of a\r
-     * number.  <code>maximumFractionDigits</code> must be greater than or equal to\r
-     * <code>minimumFractionDigits</code>.\r
-     *\r
-     * @serial\r
-     * @see #getMaximumFractionDigits\r
-     */\r
-    private int    maximumFractionDigits = 3;    // invariant, >= minFractionDigits\r
-\r
-    /**\r
-     * The minimum number of digits allowed in the fractional portion of a\r
-     * number.  <code>minimumFractionDigits</code> must be less than or equal to\r
-     * <code>maximumFractionDigits</code>.\r
-     *\r
-     * @serial\r
-     * @see #getMinimumFractionDigits\r
-     */\r
-    private int    minimumFractionDigits = 0;\r
-\r
-    /**\r
-     * Currency object used to format currencies.  Subclasses may\r
-     * ignore this if they are not currency formats.  This will be\r
-     * null unless a subclass sets it to a non-null value.\r
-     * @since ICU 2.6\r
-     */\r
-    private Currency currency;\r
-\r
-    static final int currentSerialVersion = 1;\r
-\r
-    /**\r
-     * Describes the version of <code>NumberFormat</code> present on the stream.\r
-     * Possible values are:\r
-     * <ul>\r
-     * <li><b>0</b> (or uninitialized): the JDK 1.1 version of the stream format.\r
-     *     In this version, the <code>int</code> fields such as\r
-     *     <code>maximumIntegerDigits</code> were not present, and the <code>byte</code>\r
-     *     fields such as <code>maxIntegerDigits</code> are used instead.\r
-     *\r
-     * <li><b>1</b>: the JDK 1.2 version of the stream format.  The values of the\r
-     *     <code>byte</code> fields such as <code>maxIntegerDigits</code> are ignored,\r
-     *     and the <code>int</code> fields such as <code>maximumIntegerDigits</code>\r
-     *     are used instead.\r
-     * </ul>\r
-     * When streaming out a <code>NumberFormat</code>, the most recent format\r
-     * (corresponding to the highest allowable <code>serialVersionOnStream</code>)\r
-     * is always written.\r
-     *\r
-     * @serial\r
-     */\r
-    private int serialVersionOnStream = currentSerialVersion;\r
-\r
-    // Removed "implements Cloneable" clause.  Needs to update serialization\r
-    // ID for backward compatibility.\r
-    private static final long serialVersionUID = -2308460125733713944L;\r
-\r
-    /**\r
-     * Empty constructor.  Public for compatibily with JDK which lets the\r
-     * compiler generate a default public constructor even though this is\r
-     * an abstract class.\r
-     * @stable ICU 2.6\r
-     */\r
-    public NumberFormat() {\r
-    }\r
-\r
-    // new in ICU4J 3.6\r
-    private boolean parseStrict;\r
-\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-    /**\r
-     * The instances of this inner class are used as attribute keys and values\r
-     * in AttributedCharacterIterator that\r
-     * NumberFormat.formatToCharacterIterator() method returns.\r
-     * <p>\r
-     * There is no public constructor to this class, the only instances are the\r
-     * constants defined here.\r
-     * <p>\r
-     * @stable ICU 3.6\r
-     */\r
-    public static class Field extends Format.Field {\r
-        // generated by serialver from JDK 1.4.1_01\r
-        static final long serialVersionUID = -4516273749929385842L;\r
-        \r
-        /**\r
-         * @stable ICU 3.6\r
-         */\r
-        public static final Field SIGN = new Field("sign");\r
-\r
-        /**\r
-         * @stable ICU 3.6\r
-         */\r
-        public static final Field INTEGER = new Field("integer");\r
-\r
-        /**\r
-         * @stable ICU 3.6\r
-         */\r
-        public static final Field FRACTION = new Field("fraction");\r
-\r
-        /**\r
-         * @stable ICU 3.6\r
-         */\r
-        public static final Field EXPONENT = new Field("exponent");\r
-\r
-        /**\r
-         * @stable ICU 3.6\r
-         */\r
-        public static final Field EXPONENT_SIGN = new Field("exponent sign");\r
-\r
-        /**\r
-         * @stable ICU 3.6\r
-         */\r
-        public static final Field EXPONENT_SYMBOL = new Field("exponent symbol");\r
-\r
-        /**\r
-         * @stable ICU 3.6\r
-         */\r
-        public static final Field DECIMAL_SEPARATOR = new Field("decimal separator");\r
-        /**\r
-         * @stable ICU 3.6\r
-         */\r
-        public static final Field GROUPING_SEPARATOR = new Field("grouping separator");\r
-\r
-        /**\r
-         * @stable ICU 3.6\r
-         */\r
-        public static final Field PERCENT = new Field("percent");\r
-\r
-        /**\r
-         * @stable ICU 3.6\r
-         */\r
-        public static final Field PERMILLE = new Field("per mille");\r
-\r
-        /**\r
-         * @stable ICU 3.6\r
-         */\r
-        public static final Field CURRENCY = new Field("currency");\r
-\r
-        /**\r
-         * Constructs a new instance of NumberFormat.Field with the given field\r
-         * name.\r
-         * @stable ICU 3.6\r
-         */\r
-        protected Field(String fieldName) {\r
-            super(fieldName);\r
-        }\r
-\r
-        /**\r
-         * serizalization method resolve instances to the constant\r
-         * NumberFormat.Field values\r
-         * @stable ICU 3.6\r
-         */\r
-        protected Object readResolve() throws InvalidObjectException {\r
-            if (this.getName().equals(INTEGER.getName()))\r
-                return INTEGER;\r
-            if (this.getName().equals(FRACTION.getName()))\r
-                return FRACTION;\r
-            if (this.getName().equals(EXPONENT.getName()))\r
-                return EXPONENT;\r
-            if (this.getName().equals(EXPONENT_SIGN.getName()))\r
-                return EXPONENT_SIGN;\r
-            if (this.getName().equals(EXPONENT_SYMBOL.getName()))\r
-                return EXPONENT_SYMBOL;\r
-            if (this.getName().equals(CURRENCY.getName()))\r
-                return CURRENCY;\r
-            if (this.getName().equals(DECIMAL_SEPARATOR.getName()))\r
-                return DECIMAL_SEPARATOR;\r
-            if (this.getName().equals(GROUPING_SEPARATOR.getName()))\r
-                return GROUPING_SEPARATOR;\r
-            if (this.getName().equals(PERCENT.getName()))\r
-                return PERCENT;\r
-            if (this.getName().equals(PERMILLE.getName()))\r
-                return PERMILLE;\r
-            if (this.getName().equals(SIGN.getName()))\r
-                return SIGN;\r
-\r
-            throw new InvalidObjectException("An invalid object.");\r
-        }\r
-    }\r
-//#endif\r
-}\r
+//##header J2SE15
+/*
+ *******************************************************************************
+ * Copyright (C) 1996-2009, International Business Machines Corporation and    *
+ * others. All Rights Reserved.                                                *
+ *******************************************************************************
+ */
+
+package com.ibm.icu.text;
+
+import java.io.IOException;
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.math.BigInteger;
+import java.text.FieldPosition;
+import java.text.ParseException;
+import java.text.ParsePosition;
+import java.util.Collections;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.Set;
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+import java.text.Format;
+//#endif
+
+import com.ibm.icu.impl.ICUResourceBundle;
+import com.ibm.icu.impl.Utility;
+import com.ibm.icu.util.Currency;
+import com.ibm.icu.util.CurrencyAmount;
+import com.ibm.icu.util.ULocale;
+import com.ibm.icu.util.UResourceBundle;
+
+// this is an enhanced version that is based on the standard version in the JDK
+/**
+ * <code>NumberFormat</code> is the abstract base class for all number
+ * formats. This class provides the interface for formatting and parsing
+ * numbers. <code>NumberFormat</code> also provides methods for determining
+ * which locales have number formats, and what their names are.
+ *
+ * <code>NumberFormat</code> helps you to format and parse numbers for any locale.
+ * Your code can be completely independent of the locale conventions for
+ * decimal points, thousands-separators, or even the particular decimal
+ * digits used, or whether the number format is even decimal.
+ *
+ * <p>
+ * To format a number for the current Locale, use one of the factory
+ * class methods:
+ * <blockquote>
+ * <pre>
+ *  myString = NumberFormat.getInstance().format(myNumber);
+ * </pre>
+ * </blockquote>
+ * If you are formatting multiple numbers, it is
+ * more efficient to get the format and use it multiple times so that
+ * the system doesn't have to fetch the information about the local
+ * language and country conventions multiple times.
+ * <blockquote>
+ * <pre>
+ * NumberFormat nf = NumberFormat.getInstance();
+ * for (int i = 0; i < a.length; ++i) {
+ *     output.println(nf.format(myNumber[i]) + "; ");
+ * }
+ * </pre>
+ * </blockquote>
+ * To format a number for a different Locale, specify it in the
+ * call to <code>getInstance</code>.
+ * <blockquote>
+ * <pre>
+ * NumberFormat nf = NumberFormat.getInstance(Locale.FRENCH);
+ * </pre>
+ * </blockquote>
+ * You can also use a <code>NumberFormat</code> to parse numbers:
+ * <blockquote>
+ * <pre>
+ * myNumber = nf.parse(myString);
+ * </pre>
+ * </blockquote>
+ * Use <code>getInstance</code> or <code>getNumberInstance</code> to get the
+ * normal number format. Use <code>getIntegerInstance</code> to get an
+ * integer number format. Use <code>getCurrencyInstance</code> to get the
+ * currency number format. And use <code>getPercentInstance</code> to get a
+ * format for displaying percentages. With this format, a fraction like
+ * 0.53 is displayed as 53%.
+ *
+ * <p>
+ * Starting from ICU 4.2, you can use getInstance() by passing in a 'style'
+ * as parameter to get the correct instance. 
+ * For example, 
+ * use getInstance(...NUMBERSTYLE) to get the normal number format,
+ * getInstance(...PERCENTSTYLE) to get a format for displaying percentage,
+ * getInstance(...SCIENTIFICSTYLE) to get a format for displaying scientific number,
+ * getInstance(...INTEGERSTYLE) to get an integer number format,
+ * getInstance(...CURRENCYSTYLE) to get the currency number format, 
+ * in which the currency is represented by its symbol, for example, "$3.00".
+ * getInstance(...ISOCURRENCYSTYLE)  to get the currency number format, 
+ * in which the currency is represented by its ISO code, for example "USD3.00".
+ * getInstance(...PLURALCURRENCYSTYLE) to get the currency number format,
+ * in which the currency is represented by its full name in plural format,
+ * for example, "3.00 US dollars" or "1.00 US dollar".
+ *
+ *
+ * <p>
+ * You can also control the display of numbers with such methods as
+ * <code>setMinimumFractionDigits</code>.
+ * If you want even more control over the format or parsing,
+ * or want to give your users more control,
+ * you can try casting the <code>NumberFormat</code> you get from the factory methods
+ * to a <code>DecimalFormat</code>. This will work for the vast majority
+ * of locales; just remember to put it in a <code>try</code> block in case you
+ * encounter an unusual one.
+ *
+ * <p>
+ * NumberFormat is designed such that some controls
+ * work for formatting and others work for parsing.  The following is
+ * the detailed description for each these control methods,
+ * <p>
+ * setParseIntegerOnly : only affects parsing, e.g.
+ * if true,  "3456.78" -> 3456 (and leaves the parse position just after '6')
+ * if false, "3456.78" -> 3456.78 (and leaves the parse position just after '8')
+ * This is independent of formatting.  If you want to not show a decimal point
+ * where there might be no digits after the decimal point, use
+ * setDecimalSeparatorAlwaysShown on DecimalFormat.
+ * <p>
+ * You can also use forms of the <code>parse</code> and <code>format</code>
+ * methods with <code>ParsePosition</code> and <code>FieldPosition</code> to
+ * allow you to:
+ * <ul>
+ * <li> progressively parse through pieces of a string
+ * <li> align the decimal point and other areas
+ * </ul>
+ * For example, you can align numbers in two ways:
+ * <ol>
+ * <li> If you are using a monospaced font with spacing for alignment,
+ *      you can pass the <code>FieldPosition</code> in your format call, with
+ *      <code>field</code> = <code>INTEGER_FIELD</code>. On output,
+ *      <code>getEndIndex</code> will be set to the offset between the
+ *      last character of the integer and the decimal. Add
+ *      (desiredSpaceCount - getEndIndex) spaces at the front of the string.
+ *
+ * <li> If you are using proportional fonts,
+ *      instead of padding with spaces, measure the width
+ *      of the string in pixels from the start to <code>getEndIndex</code>.
+ *      Then move the pen by
+ *      (desiredPixelWidth - widthToAlignmentPoint) before drawing the text.
+ *      It also works where there is no decimal, but possibly additional
+ *      characters at the end, e.g., with parentheses in negative
+ *      numbers: "(12)" for -12.
+ * </ol>
+ *
+ * <h4>Synchronization</h4>
+ * <p>
+ * Number formats are generally not synchronized. It is recommended to create 
+ * separate format instances for each thread. If multiple threads access a format
+ * concurrently, it must be synchronized externally. 
+ * <p>
+ *
+ * <h4>DecimalFormat</h4>
+ * <p>DecimalFormat is the concrete implementation of NumberFormat, and the
+ * NumberFormat API is essentially an abstraction from DecimalFormat's API.
+ * Refer to DecimalFormat for more information about this API.</p>
+ *
+ * see          DecimalFormat
+ * see          java.text.ChoiceFormat
+ * @author       Mark Davis
+ * @author       Helena Shih
+ * @author       Alan Liu
+ * @stable ICU 2.0
+ */
+public abstract class NumberFormat extends UFormat {
+
+    /**
+     * Constants to specify normal number style of format.
+     * @draft ICU 4.2
+     * @provisional This API might change or be removed in a future release.
+     */
+    public static final int NUMBERSTYLE = 0;
+    /**
+     * Constants to specify currency style of format which uses currency symbol
+     * to represent currency, for example: "$3.00".
+     * @draft ICU 4.2
+     * @provisional This API might change or be removed in a future release.
+     */
+    public static final int CURRENCYSTYLE = 1;
+    /**
+     * Constants to specify a style of format to display percent.
+     * @draft ICU 4.2
+     * @provisional This API might change or be removed in a future release.
+     */
+    public static final int PERCENTSTYLE = 2;
+    /**
+     * Constants to specify a style of format to display scientific number.
+     * @draft ICU 4.2
+     * @provisional This API might change or be removed in a future release.
+     */
+    public static final int SCIENTIFICSTYLE = 3;
+    /**
+     * Constants to specify a integer number style format.
+     * @draft ICU 4.2
+     * @provisional This API might change or be removed in a future release.
+     */
+    public static final int INTEGERSTYLE = 4;
+    /**
+     * Constants to specify currency style of format which uses currency 
+     * ISO code to represent currency, for example: "USD3.00".
+     * @draft ICU 4.2
+     * @provisional This API might change or be removed in a future release.
+     */
+    public static final int ISOCURRENCYSTYLE = 5;
+    /**
+     * Constants to specify currency style of format which uses currency 
+     * long name with plural format to represent currency, for example,
+     * "3.00 US Dollars".
+     * @draft ICU 4.2
+     * @provisional This API might change or be removed in a future release.
+     */
+    public static final int PLURALCURRENCYSTYLE = 6;
+
+    /**
+     * Field constant used to construct a FieldPosition object. Signifies that
+     * the position of the integer part of a formatted number should be returned.
+     * @see java.text.FieldPosition
+     * @stable ICU 2.0
+     */
+    public static final int INTEGER_FIELD = 0;
+
+    /**
+     * Field constant used to construct a FieldPosition object. Signifies that
+     * the position of the fraction part of a formatted number should be returned.
+     * @see java.text.FieldPosition
+     * @stable ICU 2.0
+     */
+    public static final int FRACTION_FIELD = 1;
+
+    // changed in ICU4J
+    /**
+     * Format an object.  Change: recognizes <code>BigInteger</code>
+     * and <code>BigDecimal</code> objects.
+     * @stable ICU 2.0
+     */
+    public StringBuffer format(Object number,
+                               StringBuffer toAppendTo,
+                               FieldPosition pos)
+    {
+        if (number instanceof Long) {
+            return format(((Long)number).longValue(), toAppendTo, pos);
+        } else if (number instanceof BigInteger) {
+            return format((BigInteger) number, toAppendTo, pos);
+//#if defined(FOUNDATION10)
+//#else
+        } else if (number instanceof java.math.BigDecimal) {
+            return format((java.math.BigDecimal) number, toAppendTo, pos);
+//#endif
+        } else if (number instanceof com.ibm.icu.math.BigDecimal) {
+            return format((com.ibm.icu.math.BigDecimal) number, toAppendTo, pos);
+        } else if (number instanceof CurrencyAmount) {
+            return format((CurrencyAmount)number, toAppendTo, pos);
+        } else if (number instanceof Number) {
+            return format(((Number)number).doubleValue(), toAppendTo, pos);
+        } else {
+            throw new IllegalArgumentException("Cannot format given Object as a Number");
+        }
+    }
+
+    /**
+     * @stable ICU 2.0
+     */
+    public final Object parseObject(String source,
+                                    ParsePosition parsePosition)
+    {
+        return parse(source, parsePosition);
+    }
+
+    /**
+     * Specialization of format.
+     * @see java.text.Format#format(Object)
+     * @stable ICU 2.0
+     */
+    public final String format(double number) {
+        return format(number,new StringBuffer(),
+                      new FieldPosition(0)).toString();
+    }
+
+    /**
+     * Specialization of format.
+     * @see java.text.Format#format(Object)
+     * @stable ICU 2.0
+     */
+    public final String format(long number) {
+        StringBuffer buf = new StringBuffer(19);
+        FieldPosition pos = new FieldPosition(0);
+        format(number, buf, pos);
+        return buf.toString();
+    }
+    
+    // [NEW]
+    /**
+     * Convenience method to format a BigInteger.
+     * @stable ICU 2.0
+     */
+    public final String format(BigInteger number) {
+        return format(number, new StringBuffer(),
+                      new FieldPosition(0)).toString();
+    }
+
+//#if defined(FOUNDATION10)
+//#else
+    // [NEW]
+    /**
+     * Convenience method to format a BigDecimal.
+     * @stable ICU 2.0
+     */
+    public final String format(java.math.BigDecimal number) {
+        return format(number, new StringBuffer(),
+                      new FieldPosition(0)).toString();
+    }
+//#endif
+
+    // [NEW]
+    /**
+     * Convenience method to format an ICU BigDecimal.
+     * @stable ICU 2.0
+     */
+    public final String format(com.ibm.icu.math.BigDecimal number) {
+        return format(number, new StringBuffer(),
+                      new FieldPosition(0)).toString();
+    }
+
+    // [NEW]
+    /**
+     * Convenience method to format a CurrencyAmount.
+     * @stable ICU 3.0
+     */
+    public final String format(CurrencyAmount currAmt) {
+        return format(currAmt, new StringBuffer(),
+                      new FieldPosition(0)).toString();
+    }
+
+    /**
+     * Specialization of format.
+     * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
+     * @stable ICU 2.0
+     */
+    public abstract StringBuffer format(double number,
+                                        StringBuffer toAppendTo,
+                                        FieldPosition pos);
+
+    /**
+     * Specialization of format.
+     * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
+     * @stable ICU 2.0
+     */
+    public abstract StringBuffer format(long number,
+                                        StringBuffer toAppendTo,
+                                        FieldPosition pos);
+    // [NEW] 
+    /**
+     * Format a BigInteger.
+     * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
+     * @stable ICU 2.0
+     */
+    public abstract StringBuffer format(BigInteger number,
+                                        StringBuffer toAppendTo,
+                                        FieldPosition pos); 
+//#if defined(FOUNDATION10)
+//#else
+    
+    // [NEW]
+    /**
+     * Format a BigDecimal.
+     * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
+     * @stable ICU 2.0
+     */
+    public abstract StringBuffer format(java.math.BigDecimal number,
+                                        StringBuffer toAppendTo,
+                                        FieldPosition pos);
+//#endif
+
+    // [NEW]
+    /**
+     * Format a BigDecimal.
+     * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
+     * @stable ICU 2.0
+     */
+    public abstract StringBuffer format(com.ibm.icu.math.BigDecimal number,
+                                        StringBuffer toAppendTo,
+                                        FieldPosition pos);
+    // [NEW]
+    /**
+     * Format a CurrencyAmount.
+     * @see java.text.Format#format(Object, StringBuffer, FieldPosition)
+     * @stable ICU 3.0
+     */
+    public StringBuffer format(CurrencyAmount currAmt,
+                               StringBuffer toAppendTo,
+                               FieldPosition pos) {
+        // Default implementation -- subclasses may override
+        Currency save = getCurrency(), curr = currAmt.getCurrency();
+        boolean same = curr.equals(save);
+        if (!same) setCurrency(curr);
+        format(currAmt.getNumber(), toAppendTo, pos);
+        if (!same) setCurrency(save);
+        return toAppendTo;
+    }
+
+    /**
+     * Returns a Long if possible (e.g., within the range [Long.MIN_VALUE,
+     * Long.MAX_VALUE] and with no decimals), otherwise a Double.
+     * If IntegerOnly is set, will stop at a decimal
+     * point (or equivalent; e.g., for rational numbers "1 2/3", will stop
+     * after the 1).
+     * Does not throw an exception; if no object can be parsed, index is
+     * unchanged!
+     * @see #isParseIntegerOnly
+     * @see java.text.Format#parseObject(String, ParsePosition)
+     * @stable ICU 2.0
+     */
+    public abstract Number parse(String text, ParsePosition parsePosition);
+
+    /**
+     * Parses text from the beginning of the given string to produce a number.
+     * The method might not use the entire text of the given string.
+     *
+     * @param text A String whose beginning should be parsed.
+     * @return A Number parsed from the string.
+     * @exception ParseException if the beginning of the specified string 
+     * cannot be parsed.
+     * @see #format
+     * @stable ICU 2.0
+     */
+    //Bug 4375399 [Richard/GCL]
+    public Number parse(String text) throws ParseException {
+        ParsePosition parsePosition = new ParsePosition(0);
+        Number result = parse(text, parsePosition);
+        if (parsePosition.getIndex() == 0) {
+            throw new ParseException("Unparseable number: \"" + text + '"',
+                                     parsePosition.getErrorIndex());
+        }
+        return result;
+    }
+
+    // [NEW]
+    /**
+     * Parses text from the given string as a CurrencyAmount.  Unlike
+     * the parse() method, this method will attempt to parse a generic
+     * currency name, searching for a match of this object's locale's
+     * currency display names, or for a 3-letter ISO currency code.
+     * This method will fail if this format is not a currency format,
+     * that is, if it does not contain the currency pattern symbol
+     * (U+00A4) in its prefix or suffix.
+     *
+     * @param text the string to parse
+     * @param pos input-output position; on input, the position within
+     * text to match; must have 0 <= pos.getIndex() < text.length();
+     * on output, the position after the last matched character. If
+     * the parse fails, the position in unchanged upon output.
+     * @return a CurrencyAmount, or null upon failure
+     * @internal
+     * @deprecated This API is ICU internal only.
+     */
+    CurrencyAmount parseCurrency(String text, ParsePosition pos) {
+        // Default implementation only -- subclasses should override
+        Number n = parse(text, pos);
+        return n == null ? null : new CurrencyAmount(n, getEffectiveCurrency());
+    }
+
+    /**
+     * Returns true if this format will parse numbers as integers only.
+     * For example in the English locale, with ParseIntegerOnly true, the
+     * string "1234." would be parsed as the integer value 1234 and parsing
+     * would stop at the "." character.  The decimal separator accepted
+     * by the parse operation is locale-dependent and determined by the
+     * subclass.
+     * @return true if this will parse integers only
+     * @stable ICU 2.0
+     */
+    public boolean isParseIntegerOnly() {
+        return parseIntegerOnly;
+    }
+
+    /**
+     * Sets whether or not numbers should be parsed as integers only.
+     * @param value true if this should parse integers only
+     * @see #isParseIntegerOnly
+     * @stable ICU 2.0
+     */
+    public void setParseIntegerOnly(boolean value) {
+        parseIntegerOnly = value;
+    }
+
+    /**
+     * Sets whether strict parsing is in effect.  When this is true, the
+     * following conditions cause a parse failure (examples use the pattern "#,##0.#"):<ul>
+     * <li>Leading zeros<br>
+     * '00', '0123' fail the parse, but '0' and '0.001' pass</li>
+     * <li>Leading or doubled grouping separators<br>
+     * ',123' and '1,,234" fail</li>
+     * <li>Groups of incorrect length when grouping is used<br>
+     * '1,23' and '1234,567' fail, but '1234' passes</li>
+     * <li>Grouping separators used in numbers followed by exponents<br>
+     * '1,234E5' fails, but '1234E5' and '1,234E' pass ('E' is not an exponent when
+     * not followed by a number)</li>
+     * </ul>
+     * When strict parsing is off, leading zeros and all grouping separators are ignored.
+     * This is the default behavior.
+     * @param value True to enable strict parsing.  Default is false.
+     * @see #isParseStrict
+     * @stable ICU 3.6
+     */
+    public void setParseStrict(boolean value) {
+        parseStrict = value;
+    }
+
+    /**
+     * Return whether strict parsing is in effect.
+     * @return true if strict parsing is in effect
+     * @see #setParseStrict
+     * @stable ICU 3.6
+     */
+    public boolean isParseStrict() {
+        return parseStrict;
+    }
+
+    //============== Locale Stuff =====================
+
+    /**
+     * Returns the default number format for the current default locale.
+     * The default format is one of the styles provided by the other
+     * factory methods: getNumberInstance, getIntegerInstance,
+     * getCurrencyInstance or getPercentInstance.
+     * Exactly which one is locale-dependent.
+     * @stable ICU 2.0
+     */
+    //Bug 4408066 [Richard/GCL]
+    public final static NumberFormat getInstance() {
+        return getInstance(ULocale.getDefault(), NUMBERSTYLE);
+    }
+
+    /**
+     * Returns the default number format for the specified locale.
+     * The default format is one of the styles provided by the other
+     * factory methods: getNumberInstance, getCurrencyInstance or getPercentInstance.
+     * Exactly which one is locale-dependent.
+     * @stable ICU 2.0
+     */
+    public static NumberFormat getInstance(Locale inLocale) {
+        return getInstance(ULocale.forLocale(inLocale), NUMBERSTYLE);
+    }
+
+    /**
+     * Returns the default number format for the specified locale.
+     * The default format is one of the styles provided by the other
+     * factory methods: getNumberInstance, getCurrencyInstance or getPercentInstance.
+     * Exactly which one is locale-dependent.
+     * @stable ICU 3.2
+     */
+    public static NumberFormat getInstance(ULocale inLocale) {
+        return getInstance(inLocale, NUMBERSTYLE);
+    }
+
+    /**
+     * Returns a specific style number format for default locale.
+     * @param style  number format style
+     * @draft ICU 4.2
+     * @provisional This API might change or be removed in a future release.
+     */
+    public final static NumberFormat getInstance(int style) {
+        return getInstance(ULocale.getDefault(), style);
+    }
+
+    /**
+     * Returns a specific style number format for a specific locale.
+     * @param inLocale  the specific locale.
+     * @param style     number format style
+     * @draft ICU 4.2
+     * @provisional This API might change or be removed in a future release.
+     */
+    public static NumberFormat getInstance(Locale inLocale, int style) {
+        return getInstance(ULocale.forLocale(inLocale), style);
+    }
+
+
+    /**
+     * Returns a general-purpose number format for the current default locale.
+     * @stable ICU 2.0
+     */
+    public final static NumberFormat getNumberInstance() {
+        return getInstance(ULocale.getDefault(), NUMBERSTYLE);
+    }
+
+    /**
+     * Returns a general-purpose number format for the specified locale.
+     * @stable ICU 2.0
+     */
+    public static NumberFormat getNumberInstance(Locale inLocale) {
+        return getInstance(ULocale.forLocale(inLocale), NUMBERSTYLE);
+    }
+
+    /**
+     * Returns a general-purpose number format for the specified locale.
+     * @stable ICU 3.2
+     */
+    public static NumberFormat getNumberInstance(ULocale inLocale) {
+        return getInstance(inLocale, NUMBERSTYLE);
+    }
+
+    /**
+     * Returns an integer number format for the current default locale. The
+     * returned number format is configured to round floating point numbers
+     * to the nearest integer using IEEE half-even rounding (see {@link 
+     * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,
+     * and to parse only the integer part of an input string (see {@link
+     * #isParseIntegerOnly isParseIntegerOnly}).
+     *
+     * @return a number format for integer values
+     * @stable ICU 2.0
+     */
+    //Bug 4408066 [Richard/GCL]
+    public final static NumberFormat getIntegerInstance() {
+        return getInstance(ULocale.getDefault(), INTEGERSTYLE);
+    }
+
+    /**
+     * Returns an integer number format for the specified locale. The
+     * returned number format is configured to round floating point numbers
+     * to the nearest integer using IEEE half-even rounding (see {@link 
+     * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,
+     * and to parse only the integer part of an input string (see {@link
+     * #isParseIntegerOnly isParseIntegerOnly}).
+     *
+     * @param inLocale the locale for which a number format is needed
+     * @return a number format for integer values
+     * @stable ICU 2.0
+     */
+    //Bug 4408066 [Richard/GCL]
+    public static NumberFormat getIntegerInstance(Locale inLocale) {
+        return getInstance(ULocale.forLocale(inLocale), INTEGERSTYLE);
+    }
+
+    /**
+     * Returns an integer number format for the specified locale. The
+     * returned number format is configured to round floating point numbers
+     * to the nearest integer using IEEE half-even rounding (see {@link 
+     * com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN ROUND_HALF_EVEN}) for formatting,
+     * and to parse only the integer part of an input string (see {@link
+     * #isParseIntegerOnly isParseIntegerOnly}).
+     *
+     * @param inLocale the locale for which a number format is needed
+     * @return a number format for integer values
+     * @stable ICU 3.2
+     */
+    public static NumberFormat getIntegerInstance(ULocale inLocale) {
+        return getInstance(inLocale, INTEGERSTYLE);
+    }
+
+    /**
+     * Returns a currency format for the current default locale.
+     * @return a number format for currency
+     * @stable ICU 2.0
+     */
+    public final static NumberFormat getCurrencyInstance() {
+        return getInstance(ULocale.getDefault(), CURRENCYSTYLE);
+    }
+
+    /**
+     * Returns a currency format for the specified locale.
+     * @return a number format for currency
+     * @stable ICU 2.0
+     */
+    public static NumberFormat getCurrencyInstance(Locale inLocale) {
+        return getInstance(ULocale.forLocale(inLocale), CURRENCYSTYLE);
+    }
+
+    /**
+     * Returns a currency format for the specified locale.
+     * @return a number format for currency
+     * @stable ICU 3.2
+     */
+    public static NumberFormat getCurrencyInstance(ULocale inLocale) {
+        return getInstance(inLocale, CURRENCYSTYLE);
+    }
+
+    /**
+     * Returns a percentage format for the current default locale.
+     * @return a number format for percents
+     * @stable ICU 2.0
+     */
+    public final static NumberFormat getPercentInstance() {
+        return getInstance(ULocale.getDefault(), PERCENTSTYLE);
+    }
+
+    /**
+     * Returns a percentage format for the specified locale.
+     * @return a number format for percents
+     * @stable ICU 2.0
+     */
+    public static NumberFormat getPercentInstance(Locale inLocale) {
+        return getInstance(ULocale.forLocale(inLocale), PERCENTSTYLE);
+    }
+
+    /**
+     * Returns a percentage format for the specified locale.
+     * @return a number format for percents
+     * @stable ICU 3.2
+     */
+    public static NumberFormat getPercentInstance(ULocale inLocale) {
+        return getInstance(inLocale, PERCENTSTYLE);
+    }
+
+    // [NEW]
+    /**
+     * Returns a scientific format for the current default locale.
+     * @return a scientific number format
+     * @stable ICU 2.0
+     */
+    public final static NumberFormat getScientificInstance() {
+        return getInstance(ULocale.getDefault(), SCIENTIFICSTYLE);
+    }
+
+    // [NEW]
+    /**
+     * Returns a scientific format for the specified locale.
+     * @return a scientific number format
+     * @stable ICU 2.0
+     */
+    public static NumberFormat getScientificInstance(Locale inLocale) {
+        return getInstance(ULocale.forLocale(inLocale), SCIENTIFICSTYLE);
+    }
+
+    // [NEW]
+    /**
+     * Returns a scientific format for the specified locale.
+     * @return a scientific number format
+     * @stable ICU 3.2
+     */
+    public static NumberFormat getScientificInstance(ULocale inLocale) {
+        return getInstance(inLocale, SCIENTIFICSTYLE);
+    }
+
+    // ===== Factory stuff =====
+    /**
+     * A NumberFormatFactory is used to register new number formats.  The factory
+     * should be able to create any of the predefined formats for each locale it
+     * supports.  When registered, the locales it supports extend or override the
+     * locales already supported by ICU.
+     * <p><b>Note:</b> as of ICU4J 3.2, the default API for NumberFormatFactory uses
+     * ULocale instead of Locale.  Instead of overriding createFormat(Locale, int),
+     * new implementations should override createFactory(ULocale, int).  Note that
+     * one of these two methods <b>MUST</b> be overridden or else an infinite
+     * loop will occur.
+     *
+     * @stable ICU 2.6
+     */
+    public static abstract class NumberFormatFactory {
+        /**
+         * Value passed to format requesting a default number format.
+         * @stable ICU 2.6
+         */
+        public static final int FORMAT_NUMBER = NUMBERSTYLE;
+
+        /**
+         * Value passed to format requesting a currency format.
+         * @stable ICU 2.6
+         */
+        public static final int FORMAT_CURRENCY = CURRENCYSTYLE;
+
+        /**
+         * Value passed to format requesting a percent format.
+         * @stable ICU 2.6
+         */
+        public static final int FORMAT_PERCENT = PERCENTSTYLE;
+
+        /**
+         * Value passed to format requesting a scientific format.
+         * @stable ICU 2.6
+         */
+        public static final int FORMAT_SCIENTIFIC = SCIENTIFICSTYLE;
+
+        /**
+         * Value passed to format requesting an integer format.
+         * @stable ICU 2.6
+         */
+        public static final int FORMAT_INTEGER = INTEGERSTYLE;
+
+        /**
+         * Returns true if this factory is visible.  Default is true.
+         * If not visible, the locales supported by this factory will not
+         * be listed by getAvailableLocales.  This value must not change.
+         * @return true if the factory is visible.
+         * @stable ICU 2.6
+         */
+        ///CLOVER:OFF
+        public boolean visible() {
+            return true;
+        }
+        ///CLOVER:ON
+
+        /**
+         * Returns an immutable collection of the locale names directly 
+         * supported by this factory.
+         * @return the supported locale names.
+         * @stable ICU 2.6
+         */
+         public abstract Set getSupportedLocaleNames();
+
+        /**
+         * Returns a number format of the appropriate type.  If the locale
+         * is not supported, return null.  If the locale is supported, but
+         * the type is not provided by this service, return null.  Otherwise
+         * return an appropriate instance of NumberFormat.
+         * <b>Note:</b> as of ICU4J 3.2, implementations should override
+         * this method instead of createFormat(Locale, int).
+         * @param loc the locale for which to create the format
+         * @param formatType the type of format
+         * @return the NumberFormat, or null.
+         * @stable ICU 3.2
+         */
+        public NumberFormat createFormat(ULocale loc, int formatType) {
+            return createFormat(loc.toLocale(), formatType);
+        }
+
+        /**
+         * Returns a number format of the appropriate type.  If the locale
+         * is not supported, return null.  If the locale is supported, but
+         * the type is not provided by this service, return null.  Otherwise
+         * return an appropriate instance of NumberFormat.
+         * <b>Note:</b> as of ICU4J 3.2, createFormat(ULocale, int) should be
+         * overridden instead of this method.  This method is no longer 
+         * abstract and delegates to that method.
+         * @param loc the locale for which to create the format
+         * @param formatType the type of format
+         * @return the NumberFormat, or null.
+         * @stable ICU 2.6
+         */
+        public NumberFormat createFormat(Locale loc, int formatType) {
+            return createFormat(ULocale.forLocale(loc), formatType);
+        }
+
+        /**
+         * @stable ICU 2.6
+         */
+        protected NumberFormatFactory() {
+        }
+    }
+
+    /**
+     * A NumberFormatFactory that supports a single locale.  It can be visible or invisible.
+     * @stable ICU 2.6
+     */
+    public static abstract class SimpleNumberFormatFactory extends NumberFormatFactory {
+        final Set localeNames;
+        final boolean visible;
+
+        /**
+         * Constructs a SimpleNumberFormatFactory with the given locale.
+         * @stable ICU 2.6
+         */
+        public SimpleNumberFormatFactory(Locale locale) {
+            this(locale, true);
+        }
+        
+        /**
+         * Constructs a SimpleNumberFormatFactory with the given locale and the
+         * visibility.
+         * @stable ICU 2.6
+         */
+        public SimpleNumberFormatFactory(Locale locale, boolean visible) {
+            localeNames = Collections.singleton(ULocale.forLocale(locale).getBaseName());
+            this.visible = visible;
+        }
+
+        /**
+         * Constructs a SimpleNumberFormatFactory with the given locale.
+         * @stable ICU 3.2
+         */
+        public SimpleNumberFormatFactory(ULocale locale) {
+            this(locale, true);
+        }
+        
+        /**
+         * Constructs a SimpleNumberFormatFactory with the given locale and the
+         * visibility.
+         * @stable ICU 3.2
+         */
+        public SimpleNumberFormatFactory(ULocale locale, boolean visible) {
+            localeNames = Collections.singleton(locale.getBaseName());
+            this.visible = visible;
+        }
+
+        /**
+         * {@inheritDoc}
+         * @stable ICU 2.6
+         */
+        public final boolean visible() {
+            return visible;
+        }
+
+        /**
+         * {@inheritDoc}
+         * @stable ICU 2.6
+         */
+        public final Set getSupportedLocaleNames() {
+            return localeNames;
+        }
+    }
+
+    // shim so we can build without service code
+    static abstract class NumberFormatShim {
+        abstract Locale[] getAvailableLocales();
+        abstract ULocale[] getAvailableULocales();
+        abstract Object registerFactory(NumberFormatFactory f);
+        abstract boolean unregister(Object k);
+        abstract NumberFormat createInstance(ULocale l, int k);
+    }
+
+    private static NumberFormatShim shim;
+    private static NumberFormatShim getShim() {
+        // Note: this instantiation is safe on loose-memory-model configurations
+        // despite lack of synchronization, since the shim instance has no state--
+        // it's all in the class init.  The worst problem is we might instantiate
+        // two shim instances, but they'll share the same state so that's ok.
+        if (shim == null) {
+            try {
+                Class cls = Class.forName("com.ibm.icu.text.NumberFormatServiceShim");
+                shim = (NumberFormatShim)cls.newInstance();
+            }
+            catch (MissingResourceException e){
+                throw e;
+            }
+            catch (Exception e) {
+                ///CLOVER:OFF
+               // e.printStackTrace();
+                throw new RuntimeException(e.getMessage());
+                ///CLOVER:ON
+            }
+        }
+        return shim;
+    }
+
+    /**
+     * Get the list of Locales for which NumberFormats are available.
+     * @return the available locales
+     * @stable ICU 2.0
+     */
+    public static Locale[] getAvailableLocales() {
+        if (shim == null) {
+            return ICUResourceBundle.getAvailableLocales(ICUResourceBundle.ICU_BASE_NAME);
+        }
+        return getShim().getAvailableLocales();
+    }
+
+    /**
+     * Get the list of Locales for which NumberFormats are available.
+     * @return the available locales
+     * @draft ICU 3.2 (retain)
+     * @provisional This API might change or be removed in a future release.
+     */
+    public static ULocale[] getAvailableULocales() {
+        if (shim == null) {
+            return ICUResourceBundle.getAvailableULocales(ICUResourceBundle.ICU_BASE_NAME);
+        }
+        return getShim().getAvailableULocales();
+    }
+
+    /**
+     * Registers a new NumberFormatFactory.  The factory is adopted by
+     * the service and must not be modified.  The returned object is a
+     * key that can be used to unregister this factory.
+     * @param factory the factory to register
+     * @return a key with which to unregister the factory
+     * @stable ICU 2.6 
+     */
+    public static Object registerFactory(NumberFormatFactory factory) {
+        if (factory == null) {
+            throw new IllegalArgumentException("factory must not be null");
+        }
+        return getShim().registerFactory(factory);
+    }
+
+    /**
+     * Unregister the factory or instance associated with this key (obtained from
+     * registerInstance or registerFactory).
+     * @param registryKey a key obtained from registerFactory
+     * @return true if the object was successfully unregistered
+     * @stable ICU 2.6
+     */
+    public static boolean unregister(Object registryKey) {
+        if (registryKey == null) {
+            throw new IllegalArgumentException("registryKey must not be null");
+        }
+
+        if (shim == null) {
+            return false;
+        }
+
+        return shim.unregister(registryKey);
+    }
+
+    // ===== End of factory stuff =====
+
+    /**
+     * Overrides hashCode
+     * @stable ICU 2.0
+     */
+    public int hashCode() {
+        return maximumIntegerDigits * 37 + maxFractionDigits;
+        // just enough fields for a reasonable distribution
+    }
+
+    /**
+     * Overrides equals.  Two NumberFormats are equal if they are of the same class
+     * and the settings (groupingUsed, parseIntegerOnly, maximumIntegerDigits, etc.
+     * are equal.
+     * @param obj the object to compare against
+     * @return true if the object is equal to this.
+     * @stable ICU 2.0
+     */
+    public boolean equals(Object obj) {
+        if (obj == null) return false;
+        if (this == obj)
+            return true;
+        if (getClass() != obj.getClass())
+            return false;
+        NumberFormat other = (NumberFormat) obj;
+        return maximumIntegerDigits == other.maximumIntegerDigits
+            && minimumIntegerDigits == other.minimumIntegerDigits
+            && maximumFractionDigits == other.maximumFractionDigits
+            && minimumFractionDigits == other.minimumFractionDigits
+            && groupingUsed == other.groupingUsed
+            && parseIntegerOnly == other.parseIntegerOnly
+            && parseStrict == other.parseStrict;
+    }
+
+    /**
+     * Overrides Cloneable.
+     * @stable ICU 2.0
+     */
+    public Object clone()
+    {
+        NumberFormat other = (NumberFormat) super.clone();
+        return other;
+    }
+
+    /**
+     * Returns true if grouping is used in this format. For example, in the
+     * en_US locale, with grouping on, the number 1234567 will be formatted
+     * as "1,234,567". The grouping separator as well as the size of each group
+     * is locale-dependent and is determined by subclasses of NumberFormat.
+     * Grouping affects both parsing and formatting.
+     * @return true if grouping is used
+     * @see #setGroupingUsed
+     * @stable ICU 2.0
+     */
+    public boolean isGroupingUsed() {
+        return groupingUsed;
+    }
+
+    /**
+     * Sets whether or not grouping will be used in this format.  Grouping
+     * affects both parsing and formatting.
+     * @see #isGroupingUsed
+     * @param newValue true to use grouping.
+     * @stable ICU 2.0
+     */
+    public void setGroupingUsed(boolean newValue) {
+        groupingUsed = newValue;
+    }
+
+    /**
+     * Returns the maximum number of digits allowed in the integer portion of a
+     * number.  The default value is 40, which subclasses can override.
+     * When formatting, the exact behavior when this value is exceeded is
+     * subclass-specific.  When parsing, this has no effect.
+     * @return the maximum number of integer digits
+     * @see #setMaximumIntegerDigits
+     * @stable ICU 2.0
+     */
+    public int getMaximumIntegerDigits() {
+        return maximumIntegerDigits;
+    }
+
+    /**
+     * Sets the maximum number of digits allowed in the integer portion of a
+     * number. This must be >= minimumIntegerDigits.  If the
+     * new value for maximumIntegerDigits is less than the current value
+     * of minimumIntegerDigits, then minimumIntegerDigits will also be set to
+     * the new value.
+     * @param newValue the maximum number of integer digits to be shown; if
+     * less than zero, then zero is used.  Subclasses might enforce an
+     * upper limit to this value appropriate to the numeric type being formatted.
+     * @see #getMaximumIntegerDigits
+     * @stable ICU 2.0
+     */
+    public void setMaximumIntegerDigits(int newValue) {
+        maximumIntegerDigits = Math.max(0,newValue);
+        if (minimumIntegerDigits > maximumIntegerDigits)
+            minimumIntegerDigits = maximumIntegerDigits;
+    }
+
+    /**
+     * Returns the minimum number of digits allowed in the integer portion of a
+     * number.  The default value is 1, which subclasses can override.
+     * When formatting, if this value is not reached, numbers are padded on the
+     * left with the locale-specific '0' character to ensure at least this
+     * number of integer digits.  When parsing, this has no effect.
+     * @return the minimum number of integer digits
+     * @see #setMinimumIntegerDigits
+     * @stable ICU 2.0
+     */
+    public int getMinimumIntegerDigits() {
+        return minimumIntegerDigits;
+    }
+
+    /**
+     * Sets the minimum number of digits allowed in the integer portion of a
+     * number.  This must be <= maximumIntegerDigits.  If the
+     * new value for minimumIntegerDigits is more than the current value
+     * of maximumIntegerDigits, then maximumIntegerDigits will also be set to
+     * the new value.
+     * @param newValue the minimum number of integer digits to be shown; if
+     * less than zero, then zero is used. Subclasses might enforce an
+     * upper limit to this value appropriate to the numeric type being formatted.
+     * @see #getMinimumIntegerDigits
+     * @stable ICU 2.0
+     */
+    public void setMinimumIntegerDigits(int newValue) {
+        minimumIntegerDigits = Math.max(0,newValue);
+        if (minimumIntegerDigits > maximumIntegerDigits)
+            maximumIntegerDigits = minimumIntegerDigits;
+    }
+
+    /**
+     * Returns the maximum number of digits allowed in the fraction
+     * portion of a number.  The default value is 3, which subclasses
+     * can override.  When formatting, the exact behavior when this
+     * value is exceeded is subclass-specific.  When parsing, this has 
+     * no effect.
+     * @return the maximum number of fraction digits
+     * @see #setMaximumFractionDigits
+     * @stable ICU 2.0 
+     */
+    public int getMaximumFractionDigits() {
+        return maximumFractionDigits;
+    }
+
+    /**
+     * Sets the maximum number of digits allowed in the fraction portion of a
+     * number. This must be >= minimumFractionDigits.  If the
+     * new value for maximumFractionDigits is less than the current value
+     * of minimumFractionDigits, then minimumFractionDigits will also be set to
+     * the new value.
+     * @param newValue the maximum number of fraction digits to be shown; if
+     * less than zero, then zero is used. The concrete subclass may enforce an
+     * upper limit to this value appropriate to the numeric type being formatted.
+     * @see #getMaximumFractionDigits
+     * @stable ICU 2.0
+     */
+    public void setMaximumFractionDigits(int newValue) {
+        maximumFractionDigits = Math.max(0,newValue);
+        if (maximumFractionDigits < minimumFractionDigits)
+            minimumFractionDigits = maximumFractionDigits;
+    }
+
+    /**
+     * Returns the minimum number of digits allowed in the fraction portion of a
+     * number.  The default value is 0, which subclasses can override.
+     * When formatting, if this value is not reached, numbers are padded on
+     * the right with the locale-specific '0' character to ensure at least
+     * this number of fraction digits.  When parsing, this has no effect.
+     * @return the minimum number of fraction digits
+     * @see #setMinimumFractionDigits
+     * @stable ICU 2.0
+     */
+    public int getMinimumFractionDigits() {
+        return minimumFractionDigits;
+    }
+
+    /**
+     * Sets the minimum number of digits allowed in the fraction portion of a
+     * number.  This must be <= maximumFractionDigits.  If the
+     * new value for minimumFractionDigits exceeds the current value
+     * of maximumFractionDigits, then maximumFractionDigits will also be set to
+     * the new value.
+     * @param newValue the minimum number of fraction digits to be shown; if
+     * less than zero, then zero is used.  Subclasses might enforce an
+     * upper limit to this value appropriate to the numeric type being formatted.
+     * @see #getMinimumFractionDigits
+     * @stable ICU 2.0
+     */
+    public void setMinimumFractionDigits(int newValue) {
+        minimumFractionDigits = Math.max(0,newValue);
+        if (maximumFractionDigits < minimumFractionDigits)
+            maximumFractionDigits = minimumFractionDigits;
+    }
+
+    /**
+     * Sets the <tt>Currency</tt> object used to display currency
+     * amounts.  This takes effect immediately, if this format is a
+     * currency format.  If this format is not a currency format, then
+     * the currency object is used if and when this object becomes a
+     * currency format.
+     * @param theCurrency new currency object to use.  May be null for
+     * some subclasses.
+     * @stable ICU 2.6
+     */
+    public void setCurrency(Currency theCurrency) {
+        currency = theCurrency;
+    }
+
+    /**
+     * Gets the <tt>Currency</tt> object used to display currency
+     * amounts.  This may be null.
+     * @stable ICU 2.6
+     */
+    public Currency getCurrency() {
+        return currency;
+    }
+    
+    /**
+     * Returns the currency in effect for this formatter.  Subclasses
+     * should override this method as needed.  Unlike getCurrency(),
+     * this method should never return null.
+     * @return a non-null Currency
+     * @internal
+     * @deprecated This API is ICU internal only.
+     */
+    protected Currency getEffectiveCurrency() {
+        Currency c = getCurrency();
+        if (c == null) {
+            ULocale uloc = getLocale(ULocale.VALID_LOCALE);
+            if (uloc == null) {
+                uloc = ULocale.getDefault();
+            }
+            c = Currency.getInstance(uloc);
+        }
+        return c;
+    }
+
+    /**
+     * Get the rounding mode used in this NumberFormat.  The default implementation of
+     * tis method in NumberFormat always throws <code>UnsupportedOperationException</code>.
+     * @return A rounding mode, between <code>BigDecimal.ROUND_UP</code>
+     * and <code>BigDecimal.ROUND_UNNECESSARY</code>.
+     * @see #setRoundingMode(int)
+     * @stable ICU 4.0
+     */
+    public int getRoundingMode() {
+        throw new UnsupportedOperationException("getRoundingMode must be implemented by the subclass implementation.");
+    }
+
+    /**
+     * Set the rounding mode used in this NumberFormat.  The default implementation of
+     * tis method in NumberFormat always throws <code>UnsupportedOperationException</code>.
+     * @param roundingMode A rounding mode, between
+     * <code>BigDecimal.ROUND_UP</code> and
+     * <code>BigDecimal.ROUND_UNNECESSARY</code>.
+     * @see #getRoundingMode()
+     * @stable ICU 4.0
+     */
+    public void setRoundingMode(int roundingMode) {
+        throw new UnsupportedOperationException("setRoundingMode must be implemented by the subclass implementation.");
+    }
+
+
+    /**
+     * Returns a specific style number format for a specific locale.
+     * @param desiredLocale  the specific locale.
+     * @param choice         number format style
+     * @throws IllegalArgumentException  if choice is not one of
+     *                                   NUMBERSTYLE, CURRENCYSTYLE, 
+     *                                   PERCENTSTYLE, SCIENTIFICSTYLE, 
+     *                                   INTEGERSTYLE, 
+     *                                   ISOCURRENCYSTYLE, PLURALCURRENCYSTYLE,
+     * @draft ICU 4.2
+     * @provisional This API might change or be removed in a future release.
+     */
+    public static NumberFormat getInstance(ULocale desiredLocale, int choice) {
+        if (choice < NUMBERSTYLE || choice > PLURALCURRENCYSTYLE) {
+            throw new IllegalArgumentException("choice should be from NUMBERSTYLE to PLURALCURRENCYSTYLE");
+        }       
+//          if (shim == null) {
+//              return createInstance(desiredLocale, choice);
+//          } else {
+//              // TODO: shims must call setLocale() on object they create
+//              return getShim().createInstance(desiredLocale, choice);
+//          }
+        return getShim().createInstance(desiredLocale, choice);
+    }
+
+    // =======================privates===============================
+    // Hook for service
+    // [NEW]
+    static NumberFormat createInstance(ULocale desiredLocale, int choice) {
+        // If the choice is PLURALCURRENCYSTYLE, the pattern is not a single
+        // pattern, it is a pattern set, so we do not need to get them here.
+        // If the choice is ISOCURRENCYSTYLE, the pattern is the currrency
+        // pattern in the locale but by replacing the single currency sign 
+        // with double currency sign.
+        String pattern = getPattern(desiredLocale, choice);
+        DecimalFormatSymbols symbols = new DecimalFormatSymbols(desiredLocale);
+        
+        // Here we assume that the locale passed in is in the canonical
+        // form, e.g: pt_PT_@currency=PTE not pt_PT_PREEURO
+        // This style wont work for currency plural format.
+        // For currency plural format, the pattern is get from 
+        // the locale (from CurrencyUnitPatterns) without override.
+        if(choice == CURRENCYSTYLE || choice == ISOCURRENCYSTYLE){
+            String temp = symbols.getCurrencyPattern();
+            if(temp!=null){
+                pattern = temp;
+            }
+        }
+
+        // replace single currency sign in the pattern with double currency sign
+        // if the choice is ISOCURRENCYSTYLE.
+        if (choice == ISOCURRENCYSTYLE) {
+            pattern = Utility.replace(pattern, "\u00A4", doubleCurrencyStr);
+        }
+
+        NumberingSystem ns = NumberingSystem.getInstance(desiredLocale);
+        if ( ns == null ) {
+            return null;
+        }
+
+        NumberFormat format;
+
+        if ( ns != null && ns.isAlgorithmic()) {
+            String nsDesc;
+            String nsRuleSetGroup;
+            String nsRuleSetName;
+            ULocale nsLoc;
+            int desiredRulesType = RuleBasedNumberFormat.NUMBERING_SYSTEM;
+
+            nsDesc = ns.getDescription();
+            int firstSlash = nsDesc.indexOf("/");
+            int lastSlash = nsDesc.lastIndexOf("/");
+
+            if ( lastSlash > firstSlash ) {
+               String nsLocID = nsDesc.substring(0,firstSlash);
+               nsRuleSetGroup = nsDesc.substring(firstSlash+1,lastSlash);
+               nsRuleSetName = nsDesc.substring(lastSlash+1);
+
+               nsLoc = new ULocale(nsLocID);
+               if ( nsRuleSetGroup.equals("SpelloutRules")) {
+                   desiredRulesType = RuleBasedNumberFormat.SPELLOUT;
+               }
+            } else {
+                nsLoc = desiredLocale;
+                nsRuleSetName = nsDesc;
+            }
+
+            RuleBasedNumberFormat r = new RuleBasedNumberFormat(nsLoc,desiredRulesType);
+            r.setDefaultRuleSet(nsRuleSetName);
+            format = r;
+        } else {
+            DecimalFormat f = new DecimalFormat(pattern, symbols, choice);
+            // System.out.println("loc: " + desiredLocale + " choice: " + choice + " pat: " + pattern + " sym: " + symbols + " result: " + format);
+                                 
+            /*Bug 4408066
+             Add codes for the new method getIntegerInstance() [Richard/GCL]
+            */
+            // TODO: revisit this -- this is almost certainly not the way we want
+            // to do this.  aliu 1/6/2004
+            if (choice == INTEGERSTYLE) {
+                f.setMaximumFractionDigits(0);
+                f.setDecimalSeparatorAlwaysShown(false);
+                f.setParseIntegerOnly(true);
+            }
+            format = f;
+       } 
+        // TODO: the actual locale of the *pattern* may differ from that
+        // for the *symbols*.  For now, we use the data for the symbols.
+        // Revisit this.
+        ULocale valid = symbols.getLocale(ULocale.VALID_LOCALE);
+        ULocale actual = symbols.getLocale(ULocale.ACTUAL_LOCALE);
+        format.setLocale(valid, actual);
+        
+        return format;
+    }
+
+    /**
+     * Returns the pattern for the provided locale and choice.
+     * @param forLocale the locale of the data.
+     * @param choice the pattern format.
+     * @return the pattern
+     * @deprecated ICU 3.4 subclassers should override getPattern(ULocale, int) instead of this method.
+     */
+    protected static String getPattern(Locale forLocale, int choice) {
+        return getPattern(ULocale.forLocale(forLocale), choice);
+    }
+
+    /**
+     * Returns the pattern for the provided locale and choice.
+     * @param forLocale the locale of the data.
+     * @param choice the pattern format.
+     * @return the pattern
+     * @stable ICU 3.2
+     */
+    protected static String getPattern(ULocale forLocale, int choice) {
+
+        /* The following code takes care of a few cases where the
+         * resource data in the underlying JDK lags the new features
+         * we have added to ICU4J: scientific notation, rounding, and
+         * secondary grouping.
+         *
+         * We detect these cases here and return various hard-coded
+         * resource data.  This is the simplest solution for now, but
+         * it is not a good long-term mechanism.
+         * 
+         * We should replace this code with a data-driven mechanism
+         * that reads the bundle com.ibm.icu.impl.data.LocaleElements
+         * and parses an exception table that overrides the standard
+         * data at java.text.resource.LocaleElements*.java.
+         * Alternatively, we should create our own copy of the
+         * resource data, and use that exclusively.
+         */
+
+        // TEMPORARY, until we get scientific patterns into the main
+        // resources:  Retrieve scientific patterns from our resources.
+        if (choice == SCIENTIFICSTYLE) {
+            // Temporarily hard code; retrieve from resource later
+            /*For ICU compatibility [Richard/GCL]*/
+            return "#E0";
+            // return NumberFormat.getBaseStringArray("NumberPatterns")[SCIENTIFICSTYLE];
+        }
+        // TEMPORARY: Use rounding for Swiss currency
+        //if (choice == CURRENCYSTYLE &&
+        //    forLocale.getCountry().equals("CH")) {
+        //    return "'Fr. '#,##0.05;'Fr.-'#,##0.05";
+        //}
+        // TEMPORARY: Special case IN number format
+        //if (choice == NUMBERSTYLE &&
+        //    forLocale.getCountry().equals("IN")) {
+        //    return "#,##,##0.###";
+        //}
+
+        // {dlf}
+        ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.
+            getBundleInstance(ICUResourceBundle.ICU_BASE_NAME, forLocale);
+        String[] numberPatterns = rb.getStringArray("NumberPatterns");
+
+        /* {dlf}
+        // Try the cache first
+        String[] numberPatterns = (String[]) cachedLocaleData.get(forLocale);
+        if (numberPatterns == null) {
+            OverlayBundle resource = new OverlayBundle(new String[]
+                { "com.ibm.icu.impl.data.LocaleElements", RESOURCE_BASE }, forLocale);
+            numberPatterns = resource.getStringArray("NumberPatterns");
+            // Update the cache
+            cachedLocaleData.put(forLocale, numberPatterns); 
+        }
+        */
+
+        /*Bug 4408066
+         Add codes for the new method getIntegerInstance() [Richard/GCL]
+        */
+        /* for ISOCURRENCYSTYLE and PLURALCURRENCYSTYLE,
+         * the pattern is the same as the pattern of CURRENCYSTYLE
+         * but by replacing the single currency sign with
+         * double currency sign or triple currency sign.
+         */
+        int entry = (choice == INTEGERSTYLE) ? NUMBERSTYLE : 
+                ((choice == ISOCURRENCYSTYLE || choice == PLURALCURRENCYSTYLE)?
+                CURRENCYSTYLE : choice); //[Richard/GCL]
+        return numberPatterns[entry]; //[Richard/GCL]
+    }
+
+    /**
+     * First, read in the default serializable data.
+     *
+     * Then, if <code>serialVersionOnStream</code> is less than 1, indicating that
+     * the stream was written by JDK 1.1,
+     * set the <code>int</code> fields such as <code>maximumIntegerDigits</code>
+     * to be equal to the <code>byte</code> fields such as <code>maxIntegerDigits</code>,
+     * since the <code>int</code> fields were not present in JDK 1.1.
+     * Finally, set serialVersionOnStream back to the maximum allowed value so that
+     * default serialization will work properly if this object is streamed out again.
+     */
+    private void readObject(ObjectInputStream stream)
+         throws IOException, ClassNotFoundException
+    {
+        stream.defaultReadObject();
+        ///CLOVER:OFF
+        // we don't have serialization data for this format
+        if (serialVersionOnStream < 1) {
+            // Didn't have additional int fields, reassign to use them.
+            maximumIntegerDigits = maxIntegerDigits;
+            minimumIntegerDigits = minIntegerDigits;
+            maximumFractionDigits = maxFractionDigits;
+            minimumFractionDigits = minFractionDigits;
+        }
+        ///CLOVER:ON
+        /*Bug 4185761
+          Validate the min and max fields [Richard/GCL]
+        */
+        if (minimumIntegerDigits > maximumIntegerDigits ||
+            minimumFractionDigits > maximumFractionDigits ||
+            minimumIntegerDigits < 0 || minimumFractionDigits < 0) {
+            throw new InvalidObjectException("Digit count range invalid");
+        }
+        serialVersionOnStream = currentSerialVersion;
+    }
+
+    /**
+     * Write out the default serializable data, after first setting
+     * the <code>byte</code> fields such as <code>maxIntegerDigits</code> to be
+     * equal to the <code>int</code> fields such as <code>maximumIntegerDigits</code>
+     * (or to <code>Byte.MAX_VALUE</code>, whichever is smaller), for compatibility
+     * with the JDK 1.1 version of the stream format.
+     */
+    private void writeObject(ObjectOutputStream stream)
+         throws IOException
+    {
+        maxIntegerDigits = (maximumIntegerDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
+            (byte)maximumIntegerDigits;
+        minIntegerDigits = (minimumIntegerDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
+            (byte)minimumIntegerDigits;
+        maxFractionDigits = (maximumFractionDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
+            (byte)maximumFractionDigits;
+        minFractionDigits = (minimumFractionDigits > Byte.MAX_VALUE) ? Byte.MAX_VALUE :
+            (byte)minimumFractionDigits;
+        stream.defaultWriteObject();
+    }
+
+// Unused -- Alan 2003-05
+//    /**
+//     * Cache to hold the NumberPatterns of a Locale.
+//     */
+//    private static final Hashtable cachedLocaleData = new Hashtable(3);
+
+      private static final char[] doubleCurrencySign = {0xA4, 0xA4};
+      private static final String doubleCurrencyStr = new String(doubleCurrencySign);
+
+    /*Bug 4408066
+      Add Field for the new method getIntegerInstance() [Richard/GCL]
+    */
+
+    /**
+     * True if the the grouping (i.e. thousands) separator is used when
+     * formatting and parsing numbers.
+     *
+     * @serial
+     * @see #isGroupingUsed
+     */
+    private boolean groupingUsed = true;
+
+    /**
+     * The maximum number of digits allowed in the integer portion of a
+     * number.  <code>maxIntegerDigits</code> must be greater than or equal to
+     * <code>minIntegerDigits</code>.
+     * <p>
+     * <strong>Note:</strong> This field exists only for serialization
+     * compatibility with JDK 1.1.  In JDK 1.2 and higher, the new
+     * <code>int</code> field <code>maximumIntegerDigits</code> is used instead.
+     * When writing to a stream, <code>maxIntegerDigits</code> is set to
+     * <code>maximumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
+     * whichever is smaller.  When reading from a stream, this field is used
+     * only if <code>serialVersionOnStream</code> is less than 1. 
+     *
+     * @serial
+     * @see #getMaximumIntegerDigits
+     */
+    private byte    maxIntegerDigits = 40;
+
+    /**
+     * The minimum number of digits allowed in the integer portion of a
+     * number.  <code>minimumIntegerDigits</code> must be less than or equal to
+     * <code>maximumIntegerDigits</code>.
+     * <p>
+     * <strong>Note:</strong> This field exists only for serialization
+     * compatibility with JDK 1.1.  In JDK 1.2 and higher, the new
+     * <code>int</code> field <code>minimumIntegerDigits</code> is used instead.
+     * When writing to a stream, <code>minIntegerDigits</code> is set to
+     * <code>minimumIntegerDigits</code> or <code>Byte.MAX_VALUE</code>,
+     * whichever is smaller.  When reading from a stream, this field is used
+     * only if <code>serialVersionOnStream</code> is less than 1. 
+     *
+     * @serial
+     * @see #getMinimumIntegerDigits
+     */
+    private byte    minIntegerDigits = 1;
+
+    /**
+     * The maximum number of digits allowed in the fractional portion of a
+     * number.  <code>maximumFractionDigits</code> must be greater than or equal to
+     * <code>minimumFractionDigits</code>.
+     * <p>
+     * <strong>Note:</strong> This field exists only for serialization
+     * compatibility with JDK 1.1.  In JDK 1.2 and higher, the new
+     * <code>int</code> field <code>maximumFractionDigits</code> is used instead.
+     * When writing to a stream, <code>maxFractionDigits</code> is set to
+     * <code>maximumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
+     * whichever is smaller.  When reading from a stream, this field is used
+     * only if <code>serialVersionOnStream</code> is less than 1. 
+     *
+     * @serial
+     * @see #getMaximumFractionDigits
+     */
+    private byte    maxFractionDigits = 3;    // invariant, >= minFractionDigits
+
+    /**
+     * The minimum number of digits allowed in the fractional portion of a
+     * number.  <code>minimumFractionDigits</code> must be less than or equal to
+     * <code>maximumFractionDigits</code>.
+     * <p>
+     * <strong>Note:</strong> This field exists only for serialization
+     * compatibility with JDK 1.1.  In JDK 1.2 and higher, the new
+     * <code>int</code> field <code>minimumFractionDigits</code> is used instead.
+     * When writing to a stream, <code>minFractionDigits</code> is set to
+     * <code>minimumFractionDigits</code> or <code>Byte.MAX_VALUE</code>,
+     * whichever is smaller.  When reading from a stream, this field is used
+     * only if <code>serialVersionOnStream</code> is less than 1. 
+     *
+     * @serial
+     * @see #getMinimumFractionDigits
+     */
+    private byte    minFractionDigits = 0;
+
+    /**
+     * True if this format will parse numbers as integers only.
+     *
+     * @serial
+     * @see #isParseIntegerOnly
+     */
+    private boolean parseIntegerOnly = false;
+
+    // new fields for 1.2.  byte is too small for integer digits.
+
+    /**
+     * The maximum number of digits allowed in the integer portion of a
+     * number.  <code>maximumIntegerDigits</code> must be greater than or equal to
+     * <code>minimumIntegerDigits</code>.
+     *
+     * @serial
+     * @see #getMaximumIntegerDigits
+     */
+    private int    maximumIntegerDigits = 40;
+
+    /**
+     * The minimum number of digits allowed in the integer portion of a
+     * number.  <code>minimumIntegerDigits</code> must be less than or equal to
+     * <code>maximumIntegerDigits</code>.
+     *
+     * @serial
+     * @see #getMinimumIntegerDigits
+     */
+    private int    minimumIntegerDigits = 1;
+
+    /**
+     * The maximum number of digits allowed in the fractional portion of a
+     * number.  <code>maximumFractionDigits</code> must be greater than or equal to
+     * <code>minimumFractionDigits</code>.
+     *
+     * @serial
+     * @see #getMaximumFractionDigits
+     */
+    private int    maximumFractionDigits = 3;    // invariant, >= minFractionDigits
+
+    /**
+     * The minimum number of digits allowed in the fractional portion of a
+     * number.  <code>minimumFractionDigits</code> must be less than or equal to
+     * <code>maximumFractionDigits</code>.
+     *
+     * @serial
+     * @see #getMinimumFractionDigits
+     */
+    private int    minimumFractionDigits = 0;
+
+    /**
+     * Currency object used to format currencies.  Subclasses may
+     * ignore this if they are not currency formats.  This will be
+     * null unless a subclass sets it to a non-null value.
+     * @since ICU 2.6
+     */
+    private Currency currency;
+
+    static final int currentSerialVersion = 1;
+
+    /**
+     * Describes the version of <code>NumberFormat</code> present on the stream.
+     * Possible values are:
+     * <ul>
+     * <li><b>0</b> (or uninitialized): the JDK 1.1 version of the stream format.
+     *     In this version, the <code>int</code> fields such as
+     *     <code>maximumIntegerDigits</code> were not present, and the <code>byte</code>
+     *     fields such as <code>maxIntegerDigits</code> are used instead.
+     *
+     * <li><b>1</b>: the JDK 1.2 version of the stream format.  The values of the
+     *     <code>byte</code> fields such as <code>maxIntegerDigits</code> are ignored,
+     *     and the <code>int</code> fields such as <code>maximumIntegerDigits</code>
+     *     are used instead.
+     * </ul>
+     * When streaming out a <code>NumberFormat</code>, the most recent format
+     * (corresponding to the highest allowable <code>serialVersionOnStream</code>)
+     * is always written.
+     *
+     * @serial
+     */
+    private int serialVersionOnStream = currentSerialVersion;
+
+    // Removed "implements Cloneable" clause.  Needs to update serialization
+    // ID for backward compatibility.
+    private static final long serialVersionUID = -2308460125733713944L;
+
+    /**
+     * Empty constructor.  Public for compatibily with JDK which lets the
+     * compiler generate a default public constructor even though this is
+     * an abstract class.
+     * @stable ICU 2.6
+     */
+    public NumberFormat() {
+    }
+
+    // new in ICU4J 3.6
+    private boolean parseStrict;
+
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+    /**
+     * The instances of this inner class are used as attribute keys and values
+     * in AttributedCharacterIterator that
+     * NumberFormat.formatToCharacterIterator() method returns.
+     * <p>
+     * There is no public constructor to this class, the only instances are the
+     * constants defined here.
+     * <p>
+     * @stable ICU 3.6
+     */
+    public static class Field extends Format.Field {
+        // generated by serialver from JDK 1.4.1_01
+        static final long serialVersionUID = -4516273749929385842L;
+        
+        /**
+         * @stable ICU 3.6
+         */
+        public static final Field SIGN = new Field("sign");
+
+        /**
+         * @stable ICU 3.6
+         */
+        public static final Field INTEGER = new Field("integer");
+
+        /**
+         * @stable ICU 3.6
+         */
+        public static final Field FRACTION = new Field("fraction");
+
+        /**
+         * @stable ICU 3.6
+         */
+        public static final Field EXPONENT = new Field("exponent");
+
+        /**
+         * @stable ICU 3.6
+         */
+        public static final Field EXPONENT_SIGN = new Field("exponent sign");
+
+        /**
+         * @stable ICU 3.6
+         */
+        public static final Field EXPONENT_SYMBOL = new Field("exponent symbol");
+
+        /**
+         * @stable ICU 3.6
+         */
+        public static final Field DECIMAL_SEPARATOR = new Field("decimal separator");
+        /**
+         * @stable ICU 3.6
+         */
+        public static final Field GROUPING_SEPARATOR = new Field("grouping separator");
+
+        /**
+         * @stable ICU 3.6
+         */
+        public static final Field PERCENT = new Field("percent");
+
+        /**
+         * @stable ICU 3.6
+         */
+        public static final Field PERMILLE = new Field("per mille");
+
+        /**
+         * @stable ICU 3.6
+         */
+        public static final Field CURRENCY = new Field("currency");
+
+        /**
+         * Constructs a new instance of NumberFormat.Field with the given field
+         * name.
+         * @stable ICU 3.6
+         */
+        protected Field(String fieldName) {
+            super(fieldName);
+        }
+
+        /**
+         * serizalization method resolve instances to the constant
+         * NumberFormat.Field values
+         * @stable ICU 3.6
+         */
+        protected Object readResolve() throws InvalidObjectException {
+            if (this.getName().equals(INTEGER.getName()))
+                return INTEGER;
+            if (this.getName().equals(FRACTION.getName()))
+                return FRACTION;
+            if (this.getName().equals(EXPONENT.getName()))
+                return EXPONENT;
+            if (this.getName().equals(EXPONENT_SIGN.getName()))
+                return EXPONENT_SIGN;
+            if (this.getName().equals(EXPONENT_SYMBOL.getName()))
+                return EXPONENT_SYMBOL;
+            if (this.getName().equals(CURRENCY.getName()))
+                return CURRENCY;
+            if (this.getName().equals(DECIMAL_SEPARATOR.getName()))
+                return DECIMAL_SEPARATOR;
+            if (this.getName().equals(GROUPING_SEPARATOR.getName()))
+                return GROUPING_SEPARATOR;
+            if (this.getName().equals(PERCENT.getName()))
+                return PERCENT;
+            if (this.getName().equals(PERMILLE.getName()))
+                return PERMILLE;
+            if (this.getName().equals(SIGN.getName()))
+                return SIGN;
+
+            throw new InvalidObjectException("An invalid object.");
+        }
+    }
+//#endif
+}