]> gitweb.fperrin.net Git - Dictionary.git/blobdiff - jars/icu4j-4_2_1-src/src/com/ibm/icu/text/DecimalFormat.java
go
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / icu / text / DecimalFormat.java
old mode 100755 (executable)
new mode 100644 (file)
index 706f010..00c02e3
-//##header\r
-/*\r
- *******************************************************************************\r
- * Copyright (C) 1996-2009, International Business Machines Corporation and    *\r
- * others. All Rights Reserved.                                                *\r
- *******************************************************************************\r
- */\r
-package com.ibm.icu.text;\r
-\r
-import java.io.IOException;\r
-import java.io.ObjectInputStream;\r
-import java.math.BigInteger;\r
-import java.text.ChoiceFormat;\r
-import java.text.FieldPosition;\r
-import java.text.ParsePosition;\r
-import java.util.HashSet;\r
-import java.util.Iterator;\r
-import java.util.Set;\r
-\r
-//#if defined(FOUNDATION10)\r
-//#else\r
-import java.io.ObjectOutputStream;\r
-//#endif\r
-\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-import java.text.AttributedCharacterIterator;\r
-import java.text.AttributedString;\r
-import java.text.Format;\r
-import java.util.ArrayList;\r
-//#endif\r
-\r
-import com.ibm.icu.impl.UCharacterProperty;\r
-import com.ibm.icu.impl.Utility;\r
-import com.ibm.icu.lang.UCharacter;\r
-import com.ibm.icu.math.BigDecimal;\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.math.MathContext;\r
-\r
-//This is an enhanced version of DecimalFormat that is based on the standard version in the JDK. \r
-/**\r
- * <code>DecimalFormat</code> is a concrete subclass of\r
- * {@link NumberFormat} that formats decimal numbers. It has a variety of\r
- * features designed to make it possible to parse and format numbers in any\r
- * locale, including support for Western, Arabic, or Indic digits.  It also\r
- * supports different flavors of numbers, including integers ("123"),\r
- * fixed-point numbers ("123.4"), scientific notation ("1.23E4"), percentages\r
- * ("12%"), and currency amounts ("$123.00", "USD123.00", "123.00 US dollars").\r
- * All of these flavors can be easily localized.\r
- *\r
- * \r
- * <p>To obtain a {@link NumberFormat} for a specific locale (including the\r
- * default locale) call one of <code>NumberFormat</code>'s factory methods such\r
- * as {@link NumberFormat#getInstance}. Do not call the <code>DecimalFormat</code>\r
- * constructors directly, unless you know what you are doing, since the\r
- * {@link NumberFormat} factory methods may return subclasses other than\r
- * <code>DecimalFormat</code>. If you need to customize the format object, do\r
- * something like this:\r
- *\r
- * <blockquote><pre>\r
- * NumberFormat f = NumberFormat.getInstance(loc);\r
- * if (f instanceof DecimalFormat) {\r
- *     ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true);\r
- * }</pre></blockquote>\r
- *\r
- * <p><strong>Example Usage</strong>\r
- *\r
- * <blockquote><pre>\r
- * <strong>// Print out a number using the localized number, currency,\r
- * // and percent format for each locale</strong>\r
- * Locale[] locales = NumberFormat.getAvailableLocales();\r
- * double myNumber = -1234.56;\r
- * NumberFormat format;\r
- * for (int j=0; j<3; ++j) {\r
- *     System.out.println("FORMAT");\r
- *     for (int i = 0; i < locales.length; ++i) {\r
- *         if (locales[i].getCountry().length() == 0) {\r
- *            // Skip language-only locales\r
- *            continue;\r
- *         }\r
- *         System.out.print(locales[i].getDisplayName());\r
- *         switch (j) {\r
- *         case 0:\r
- *             format = NumberFormat.getInstance(locales[i]); break;\r
- *         case 1:\r
- *             format = NumberFormat.getCurrencyInstance(locales[i]); break;\r
- *         default:\r
- *             format = NumberFormat.getPercentInstance(locales[i]); break;\r
- *         }\r
- *         try {\r
- *             // Assume format is a DecimalFormat\r
- *             System.out.print(": " + ((DecimalFormat) format).toPattern()\r
- *                              + " -> " + form.format(myNumber));\r
- *         } catch (Exception e) {}\r
- *         try {\r
- *             System.out.println(" -> " + format.parse(form.format(myNumber)));\r
- *         } catch (ParseException e) {}\r
- *     }\r
- * }</pre></blockquote>\r
- *\r
- * <P>\r
- * Another example use getInstance(style)\r
- * <P>\r
- * <pre>\r
- * <strong>// Print out a number using the localized number, currency,\r
- * // percent, scientific, integer, iso currency, and plural currency\r
- * // format for each locale</strong>\r
- * ULocale locale = new ULocale("en_US");\r
- * double myNumber = 1234.56;\r
- * for (int j=NumberFormat.NUMBERSTYLE; j<=NumberFormat.PLURALCURRENCYSTYLE; ++j) {\r
- *     NumberFormat format = NumberFormat.getInstance(locale, j);\r
- *     try {\r
- *         // Assume format is a DecimalFormat\r
- *         System.out.print(": " + ((DecimalFormat) format).toPattern()\r
- *                          + " -> " + form.format(myNumber));\r
- *     } catch (Exception e) {}\r
- *     try {\r
- *         System.out.println(" -> " + format.parse(form.format(myNumber)));\r
- *     } catch (ParseException e) {}\r
- * }</pre></blockquote>\r
- *\r
- * <h4>Patterns</h4>\r
- *\r
- * <p>A <code>DecimalFormat</code> consists of a <em>pattern</em> and a set of\r
- * <em>symbols</em>.  The pattern may be set directly using\r
- * {@link #applyPattern}, or indirectly using other API methods which\r
- * manipulate aspects of the pattern, such as the minimum number of integer\r
- * digits.  The symbols are stored in a {@link DecimalFormatSymbols}\r
- * object.  When using the {@link NumberFormat} factory methods, the\r
- * pattern and symbols are read from ICU's locale data.\r
- * \r
- * <h4>Special Pattern Characters</h4>\r
- *\r
- * <p>Many characters in a pattern are taken literally; they are matched during\r
- * parsing and output unchanged during formatting.  Special characters, on the\r
- * other hand, stand for other characters, strings, or classes of characters.\r
- * For example, the '#' character is replaced by a localized digit.  Often the\r
- * replacement character is the same as the pattern character; in the U.S. locale,\r
- * the ',' grouping character is replaced by ','.  However, the replacement is\r
- * still happening, and if the symbols are modified, the grouping character\r
- * changes.  Some special characters affect the behavior of the formatter by\r
- * their presence; for example, if the percent character is seen, then the\r
- * value is multiplied by 100 before being displayed.\r
- *\r
- * <p>To insert a special character in a pattern as a literal, that is, without\r
- * any special meaning, the character must be quoted.  There are some exceptions to\r
- * this which are noted below.\r
- *\r
- * <p>The characters listed here are used in non-localized patterns.  Localized\r
- * patterns use the corresponding characters taken from this formatter's\r
- * {@link DecimalFormatSymbols} object instead, and these characters lose\r
- * their special status.  Two exceptions are the currency sign and quote, which\r
- * are not localized.\r
- *\r
- * <blockquote>\r
- * <table border=0 cellspacing=3 cellpadding=0 summary="Chart showing symbol,\r
- *  location, localized, and meaning.">\r
- *   <tr bgcolor="#ccccff">\r
- *     <th align=left>Symbol\r
- *     <th align=left>Location\r
- *     <th align=left>Localized?\r
- *     <th align=left>Meaning\r
- *   <tr valign=top>\r
- *     <td><code>0</code>\r
- *     <td>Number\r
- *     <td>Yes\r
- *     <td>Digit\r
- *   <tr valign=top bgcolor="#eeeeff">\r
- *     <td><code>1-9</code>\r
- *     <td>Number\r
- *     <td>Yes\r
- *     <td>'1' through '9' indicate rounding. \r
- *         \r
- *   <tr valign=top>\r
- *     <td><code>@</code>\r
- *     <td>Number\r
- *     <td>No\r
- *     <td>Significant digit\r
- *   <tr valign=top bgcolor="#eeeeff">\r
- *     <td><code>#</code>\r
- *     <td>Number\r
- *     <td>Yes\r
- *     <td>Digit, zero shows as absent\r
- *   <tr valign=top>\r
- *     <td><code>.</code>\r
- *     <td>Number\r
- *     <td>Yes\r
- *     <td>Decimal separator or monetary decimal separator\r
- *   <tr valign=top bgcolor="#eeeeff">\r
- *     <td><code>-</code>\r
- *     <td>Number\r
- *     <td>Yes\r
- *     <td>Minus sign\r
- *   <tr valign=top>\r
- *     <td><code>,</code>\r
- *     <td>Number\r
- *     <td>Yes\r
- *     <td>Grouping separator\r
- *   <tr valign=top bgcolor="#eeeeff">\r
- *     <td><code>E</code>\r
- *     <td>Number\r
- *     <td>Yes\r
- *     <td>Separates mantissa and exponent in scientific notation.\r
- *         <em>Need not be quoted in prefix or suffix.</em>\r
- *   <tr valign=top>\r
- *     <td><code>+</code>\r
- *     <td>Exponent\r
- *     <td>Yes\r
- *     <td>Prefix positive exponents with localized plus sign.\r
- *         <em>Need not be quoted in prefix or suffix.</em>\r
- *   <tr valign=top bgcolor="#eeeeff">\r
- *     <td><code>;</code>\r
- *     <td>Subpattern boundary\r
- *     <td>Yes\r
- *     <td>Separates positive and negative subpatterns\r
- *   <tr valign=top>\r
- *     <td><code>%</code>\r
- *     <td>Prefix or suffix\r
- *     <td>Yes\r
- *     <td>Multiply by 100 and show as percentage\r
- *   <tr valign=top bgcolor="#eeeeff">\r
- *     <td><code>&#92;u2030</code>\r
- *     <td>Prefix or suffix\r
- *     <td>Yes\r
- *     <td>Multiply by 1000 and show as per mille\r
- *   <tr valign=top>\r
- *     <td><code>&#164;</code> (<code>&#92;u00A4</code>)\r
- *     <td>Prefix or suffix\r
- *     <td>No\r
- *     <td>Currency sign, replaced by currency symbol.  If\r
- *         doubled, replaced by international currency symbol.\r
- *         If tripled, replaced by currency plural names, for example,\r
- *         "US dollar" or "US dollars" for America.\r
- *         If present in a pattern, the monetary decimal separator\r
- *         is used instead of the decimal separator.\r
- *   <tr valign=top bgcolor="#eeeeff">\r
- *     <td><code>'</code>\r
- *     <td>Prefix or suffix\r
- *     <td>No\r
- *     <td>Used to quote special characters in a prefix or suffix,\r
- *         for example, <code>"'#'#"</code> formats 123 to\r
- *         <code>"#123"</code>.  To create a single quote\r
- *         itself, use two in a row: <code>"# o''clock"</code>.\r
- *   <tr valign=top>\r
- *     <td><code>*</code>\r
- *     <td>Prefix or suffix boundary\r
- *     <td>Yes\r
- *     <td>Pad escape, precedes pad character\r
- * </table>\r
- * </blockquote>\r
- *\r
- * <p>A <code>DecimalFormat</code> pattern contains a postive and negative\r
- * subpattern, for example, "#,##0.00;(#,##0.00)".  Each subpattern has a\r
- * prefix, a numeric part, and a suffix.  If there is no explicit negative\r
- * subpattern, the negative subpattern is the localized minus sign prefixed to the\r
- * positive subpattern. That is, "0.00" alone is equivalent to "0.00;-0.00".  If there\r
- * is an explicit negative subpattern, it serves only to specify the negative\r
- * prefix and suffix; the number of digits, minimal digits, and other\r
- * characteristics are ignored in the negative subpattern. That means that\r
- * "#,##0.0#;(#)" has precisely the same result as "#,##0.0#;(#,##0.0#)".\r
- *\r
- * <p>The prefixes, suffixes, and various symbols used for infinity, digits,\r
- * thousands separators, decimal separators, etc. may be set to arbitrary\r
- * values, and they will appear properly during formatting.  However, care must\r
- * be taken that the symbols and strings do not conflict, or parsing will be\r
- * unreliable.  For example, either the positive and negative prefixes or the\r
- * suffixes must be distinct for {@link #parse} to be able\r
- * to distinguish positive from negative values.  Another example is that the\r
- * decimal separator and thousands separator should be distinct characters, or\r
- * parsing will be impossible.\r
- *\r
- * <p>The <em>grouping separator</em> is a character that separates clusters of\r
- * integer digits to make large numbers more legible.  It commonly used for\r
- * thousands, but in some locales it separates ten-thousands.  The <em>grouping\r
- * size</em> is the number of digits between the grouping separators, such as 3\r
- * for "100,000,000" or 4 for "1 0000 0000". There are actually two different\r
- * grouping sizes: One used for the least significant integer digits, the\r
- * <em>primary grouping size</em>, and one used for all others, the\r
- * <em>secondary grouping size</em>.  In most locales these are the same, but\r
- * sometimes they are different. For example, if the primary grouping interval\r
- * is 3, and the secondary is 2, then this corresponds to the pattern\r
- * "#,##,##0", and the number 123456789 is formatted as "12,34,56,789".  If a\r
- * pattern contains multiple grouping separators, the interval between the last\r
- * one and the end of the integer defines the primary grouping size, and the\r
- * interval between the last two defines the secondary grouping size. All others\r
- * are ignored, so "#,##,###,####" == "###,###,####" == "##,#,###,####".\r
- *\r
- * <p>Illegal patterns, such as "#.#.#" or "#.###,###", will cause\r
- * <code>DecimalFormat</code> to throw an {@link IllegalArgumentException}\r
- * with a message that describes the problem.\r
- *\r
- * <h4>Pattern BNF</h4>\r
- *\r
- * <pre>\r
- * pattern    := subpattern (';' subpattern)?\r
- * subpattern := prefix? number exponent? suffix?\r
- * number     := (integer ('.' fraction)?) | sigDigits\r
- * prefix     := '&#92;u0000'..'&#92;uFFFD' - specialCharacters\r
- * suffix     := '&#92;u0000'..'&#92;uFFFD' - specialCharacters\r
- * integer    := '#'* '0'* '0'\r
- * fraction   := '0'* '#'*\r
- * sigDigits  := '#'* '@' '@'* '#'*\r
- * exponent   := 'E' '+'? '0'* '0'\r
- * padSpec    := '*' padChar\r
- * padChar    := '&#92;u0000'..'&#92;uFFFD' - quote\r
- * &#32;\r
- * Notation:\r
- *   X*       0 or more instances of X\r
- *   X?       0 or 1 instances of X\r
- *   X|Y      either X or Y\r
- *   C..D     any character from C up to D, inclusive\r
- *   S-T      characters in S, except those in T\r
- * </pre>\r
- * The first subpattern is for positive numbers. The second (optional)\r
- * subpattern is for negative numbers.\r
- * \r
- * <p>Not indicated in the BNF syntax above:\r
- *\r
- * <ul><li>The grouping separator ',' can occur inside the integer and\r
- * sigDigits elements, between any two pattern characters of that\r
- * element, as long as the integer or sigDigits element is not\r
- * followed by the exponent element.\r
- *\r
- * <li>Two grouping intervals are recognized: That between the\r
- *     decimal point and the first grouping symbol, and that\r
- *     between the first and second grouping symbols. These\r
- *     intervals are identical in most locales, but in some\r
- *     locales they differ. For example, the pattern\r
- *     &quot;#,##,###&quot; formats the number 123456789 as\r
- *     &quot;12,34,56,789&quot;.</li>\r
- * \r
- * <li>\r
- * The pad specifier <code>padSpec</code> may appear before the prefix,\r
- * after the prefix, before the suffix, after the suffix, or not at all.\r
- *\r
- * <li>\r
- * In place of '0', the digits '1' through '9' may be used to\r
- * indicate a rounding increment.\r
- * </ul>\r
- *\r
- * <h4>Parsing</h4>\r
- *\r
- * <p><code>DecimalFormat</code> parses all Unicode characters that represent\r
- * decimal digits, as defined by {@link UCharacter#digit}.  In addition,\r
- * <code>DecimalFormat</code> also recognizes as digits the ten consecutive\r
- * characters starting with the localized zero digit defined in the\r
- * {@link DecimalFormatSymbols} object.  During formatting, the\r
- * {@link DecimalFormatSymbols}-based digits are output.\r
- *\r
- * <p>During parsing, grouping separators are ignored.\r
- *\r
- * <p>For currency parsing, the formatter is able to parse every currency\r
- * style formats no matter which style the formatter is constructed with.\r
- * For example, a formatter instance gotten from \r
- * NumberFormat.getInstance(ULocale, NumberFormat.CURRENCYSTYLE) can parse\r
- * formats such as "USD1.00" and "3.00 US dollars".\r
- *\r
- * <p>If {@link #parse(String, ParsePosition)} fails to parse\r
- * a string, it returns <code>null</code> and leaves the parse position\r
- * unchanged.  The convenience method {@link #parse(String)}\r
- * indicates parse failure by throwing a {@link java.text.ParseException}.\r
- *\r
- * <h4>Formatting</h4>\r
- *\r
- * <p>Formatting is guided by several parameters, all of which can be\r
- * specified either using a pattern or using the API.  The following\r
- * description applies to formats that do not use <a href="#sci">scientific\r
- * notation</a> or <a href="#sigdig">significant digits</a>.\r
- *\r
- * <ul><li>If the number of actual integer digits exceeds the\r
- * <em>maximum integer digits</em>, then only the least significant\r
- * digits are shown.  For example, 1997 is formatted as "97" if the\r
- * maximum integer digits is set to 2.\r
- *\r
- * <li>If the number of actual integer digits is less than the\r
- * <em>minimum integer digits</em>, then leading zeros are added.  For\r
- * example, 1997 is formatted as "01997" if the minimum integer digits\r
- * is set to 5.\r
- *\r
- * <li>If the number of actual fraction digits exceeds the <em>maximum\r
- * fraction digits</em>, then half-even rounding it performed to the\r
- * maximum fraction digits.  For example, 0.125 is formatted as "0.12"\r
- * if the maximum fraction digits is 2.  This behavior can be changed\r
- * by specifying a rounding increment and a rounding mode.\r
- *\r
- * <li>If the number of actual fraction digits is less than the\r
- * <em>minimum fraction digits</em>, then trailing zeros are added.\r
- * For example, 0.125 is formatted as "0.1250" if the mimimum fraction\r
- * digits is set to 4.\r
- *\r
- * <li>Trailing fractional zeros are not displayed if they occur\r
- * <em>j</em> positions after the decimal, where <em>j</em> is less\r
- * than the maximum fraction digits. For example, 0.10004 is\r
- * formatted as "0.1" if the maximum fraction digits is four or less.\r
- * </ul>\r
- * \r
- * <p><strong>Special Values</strong>\r
- *\r
- * <p><code>NaN</code> is represented as a single character, typically\r
- * <code>&#92;uFFFD</code>.  This character is determined by the\r
- * {@link DecimalFormatSymbols} object.  This is the only value for which\r
- * the prefixes and suffixes are not used.\r
- *\r
- * <p>Infinity is represented as a single character, typically\r
- * <code>&#92;u221E</code>, with the positive or negative prefixes and suffixes\r
- * applied.  The infinity character is determined by the\r
- * {@link DecimalFormatSymbols} object.\r
- *\r
- * <a name="sci"><h4>Scientific Notation</h4></a>\r
- *\r
- * <p>Numbers in scientific notation are expressed as the product of a mantissa\r
- * and a power of ten, for example, 1234 can be expressed as 1.234 x 10<sup>3</sup>. The\r
- * mantissa is typically in the half-open interval [1.0, 10.0) or sometimes [0.0, 1.0),\r
- * but it need not be.  <code>DecimalFormat</code> supports arbitrary mantissas.\r
- * <code>DecimalFormat</code> can be instructed to use scientific\r
- * notation through the API or through the pattern.  In a pattern, the exponent\r
- * character immediately followed by one or more digit characters indicates\r
- * scientific notation.  Example: "0.###E0" formats the number 1234 as\r
- * "1.234E3".\r
- *\r
- * <ul>\r
- * <li>The number of digit characters after the exponent character gives the\r
- * minimum exponent digit count.  There is no maximum.  Negative exponents are\r
- * formatted using the localized minus sign, <em>not</em> the prefix and suffix\r
- * from the pattern.  This allows patterns such as "0.###E0 m/s".  To prefix\r
- * positive exponents with a localized plus sign, specify '+' between the\r
- * exponent and the digits: "0.###E+0" will produce formats "1E+1", "1E+0",\r
- * "1E-1", etc.  (In localized patterns, use the localized plus sign rather than\r
- * '+'.)\r
- *\r
- * <li>The minimum number of integer digits is achieved by adjusting the\r
- * exponent.  Example: 0.00123 formatted with "00.###E0" yields "12.3E-4".  This\r
- * only happens if there is no maximum number of integer digits.  If there is a\r
- * maximum, then the minimum number of integer digits is fixed at one.\r
- *\r
- * <li>The maximum number of integer digits, if present, specifies the exponent\r
- * grouping.  The most common use of this is to generate <em>engineering\r
- * notation</em>, in which the exponent is a multiple of three, e.g.,\r
- * "##0.###E0".  The number 12345 is formatted using "##0.####E0" as "12.345E3".\r
- *\r
- * <li>When using scientific notation, the formatter controls the\r
- * digit counts using significant digits logic.  The maximum number of\r
- * significant digits limits the total number of integer and fraction\r
- * digits that will be shown in the mantissa; it does not affect\r
- * parsing.  For example, 12345 formatted with "##0.##E0" is "12.3E3".\r
- * See the section on significant digits for more details.\r
- *\r
- * <li>The number of significant digits shown is determined as\r
- * follows: If areSignificantDigitsUsed() returns false, then the\r
- * minimum number of significant digits shown is one, and the maximum\r
- * number of significant digits shown is the sum of the <em>minimum\r
- * integer</em> and <em>maximum fraction</em> digits, and is\r
- * unaffected by the maximum integer digits.  If this sum is zero,\r
- * then all significant digits are shown.  If\r
- * areSignificantDigitsUsed() returns true, then the significant digit\r
- * counts are specified by getMinimumSignificantDigits() and\r
- * getMaximumSignificantDigits().  In this case, the number of\r
- * integer digits is fixed at one, and there is no exponent grouping.\r
- *\r
- * <li>Exponential patterns may not contain grouping separators.\r
- * </ul>\r
- *\r
- * <a name="sigdig"><h4>\r
- * Significant Digits</h4></a>\r
- *\r
- * <code>DecimalFormat</code> has two ways of controlling how many\r
- * digits are shows: (a) significant digits counts, or (b) integer and\r
- * fraction digit counts.  Integer and fraction digit counts are\r
- * described above.  When a formatter is using significant digits\r
- * counts, the number of integer and fraction digits is not specified\r
- * directly, and the formatter settings for these counts are ignored.\r
- * Instead, the formatter uses however many integer and fraction\r
- * digits are required to display the specified number of significant\r
- * digits.  Examples:\r
- *\r
- * <blockquote>\r
- * <table border=0 cellspacing=3 cellpadding=0>\r
- *   <tr bgcolor="#ccccff">\r
- *     <th align=left>Pattern\r
- *     <th align=left>Minimum significant digits\r
- *     <th align=left>Maximum significant digits\r
- *     <th align=left>Number\r
- *     <th align=left>Output of format()\r
- *   <tr valign=top>\r
- *     <td><code>@@@</code>\r
- *     <td>3\r
- *     <td>3\r
- *     <td>12345\r
- *     <td><code>12300</code>\r
- *   <tr valign=top bgcolor="#eeeeff">\r
- *     <td><code>@@@</code>\r
- *     <td>3\r
- *     <td>3\r
- *     <td>0.12345\r
- *     <td><code>0.123</code>\r
- *   <tr valign=top>\r
- *     <td><code>@@##</code>\r
- *     <td>2\r
- *     <td>4\r
- *     <td>3.14159\r
- *     <td><code>3.142</code>\r
- *   <tr valign=top bgcolor="#eeeeff">\r
- *     <td><code>@@##</code>\r
- *     <td>2\r
- *     <td>4\r
- *     <td>1.23004\r
- *     <td><code>1.23</code>\r
- * </table>\r
- * </blockquote>\r
- *\r
- * <ul>\r
- * <li>Significant digit counts may be expressed using patterns that\r
- * specify a minimum and maximum number of significant digits.  These\r
- * are indicated by the <code>'@'</code> and <code>'#'</code>\r
- * characters.  The minimum number of significant digits is the number\r
- * of <code>'@'</code> characters.  The maximum number of significant\r
- * digits is the number of <code>'@'</code> characters plus the number\r
- * of <code>'#'</code> characters following on the right.  For\r
- * example, the pattern <code>"@@@"</code> indicates exactly 3\r
- * significant digits.  The pattern <code>"@##"</code> indicates from\r
- * 1 to 3 significant digits.  Trailing zero digits to the right of\r
- * the decimal separator are suppressed after the minimum number of\r
- * significant digits have been shown.  For example, the pattern\r
- * <code>"@##"</code> formats the number 0.1203 as\r
- * <code>"0.12"</code>.\r
- *\r
- * <li>If a pattern uses significant digits, it may not contain a\r
- * decimal separator, nor the <code>'0'</code> pattern character.\r
- * Patterns such as <code>"@00"</code> or <code>"@.###"</code> are\r
- * disallowed.\r
- *\r
- * <li>Any number of <code>'#'</code> characters may be prepended to\r
- * the left of the leftmost <code>'@'</code> character.  These have no\r
- * effect on the minimum and maximum significant digits counts, but\r
- * may be used to position grouping separators.  For example,\r
- * <code>"#,#@#"</code> indicates a minimum of one significant digits,\r
- * a maximum of two significant digits, and a grouping size of three.\r
- *\r
- * <li>In order to enable significant digits formatting, use a pattern\r
- * containing the <code>'@'</code> pattern character.  Alternatively,\r
- * call {@link #setSignificantDigitsUsed setSignificantDigitsUsed(true)}.\r
- *\r
- * <li>In order to disable significant digits formatting, use a\r
- * pattern that does not contain the <code>'@'</code> pattern\r
- * character. Alternatively, call {@link #setSignificantDigitsUsed\r
- * setSignificantDigitsUsed(false)}.\r
- *\r
- * <li>The number of significant digits has no effect on parsing.\r
- *\r
- * <li>Significant digits may be used together with exponential notation. Such\r
- * patterns are equivalent to a normal exponential pattern with a minimum and\r
- * maximum integer digit count of one, a minimum fraction digit count of\r
- * <code>getMinimumSignificantDigits() - 1</code>, and a maximum fraction digit\r
- * count of <code>getMaximumSignificantDigits() - 1</code>. For example, the\r
- * pattern <code>"@@###E0"</code> is equivalent to <code>"0.0###E0"</code>.\r
- *\r
- * <li>If signficant digits are in use, then the integer and fraction\r
- * digit counts, as set via the API, are ignored.  If significant\r
- * digits are not in use, then the signficant digit counts, as set via\r
- * the API, are ignored.\r
- *\r
- * </ul>\r
- * \r
- * <h4>\r
- * Padding</h4>\r
- *\r
- * <p><code>DecimalFormat</code> supports padding the result of\r
- * {@link #format} to a specific width.  Padding may be specified either\r
- * through the API or through the pattern syntax.  In a pattern the pad escape\r
- * character, followed by a single pad character, causes padding to be parsed\r
- * and formatted.  The pad escape character is '*' in unlocalized patterns, and\r
- * can be localized using {@link DecimalFormatSymbols#setPadEscape}.  For\r
- * example, <code>"$*x#,##0.00"</code> formats 123 to <code>"$xx123.00"</code>,\r
- * and 1234 to <code>"$1,234.00"</code>.\r
- *\r
- * <ul>\r
- * <li>When padding is in effect, the width of the positive subpattern,\r
- * including prefix and suffix, determines the format width.  For example, in\r
- * the pattern <code>"* #0 o''clock"</code>, the format width is 10.\r
- *\r
- * <li>The width is counted in 16-bit code units (Java <code>char</code>s).\r
- *\r
- * <li>Some parameters which usually do not matter have meaning when padding is\r
- * used, because the pattern width is significant with padding.  In the pattern\r
- * "* ##,##,#,##0.##", the format width is 14.  The initial characters "##,##,"\r
- * do not affect the grouping size or maximum integer digits, but they do affect\r
- * the format width.\r
- *\r
- * <li>Padding may be inserted at one of four locations: before the prefix,\r
- * after the prefix, before the suffix, or after the suffix.  If padding is\r
- * specified in any other location, {@link #applyPattern} throws an {@link\r
- * IllegalArgumentException}.  If there is no prefix, before the\r
- * prefix and after the prefix are equivalent, likewise for the suffix.\r
- *\r
- * <li>When specified in a pattern, the 16-bit <code>char</code> immediately\r
- * following the pad escape is the pad character. This may be any character,\r
- * including a special pattern character. That is, the pad escape\r
- * <em>escapes</em> the following character. If there is no character after\r
- * the pad escape, then the pattern is illegal.\r
- *\r
- * </ul>\r
- *\r
- * <p>\r
- * <strong>Rounding</strong>\r
- *\r
- * <p><code>DecimalFormat</code> supports rounding to a specific increment.  For\r
- * example, 1230 rounded to the nearest 50 is 1250.  1.234 rounded to the\r
- * nearest 0.65 is 1.3.  The rounding increment may be specified through the API\r
- * or in a pattern.  To specify a rounding increment in a pattern, include the\r
- * increment in the pattern itself.  "#,#50" specifies a rounding increment of\r
- * 50.  "#,##0.05" specifies a rounding increment of 0.05.\r
- *\r
- * <ul>\r
- * <li>Rounding only affects the string produced by formatting.  It does\r
- * not affect parsing or change any numerical values.\r
- *\r
- * <li>A <em>rounding mode</em> determines how values are rounded; see the\r
- * {@link com.ibm.icu.math.BigDecimal} documentation for a description of the\r
- * modes.  Rounding increments specified in patterns use the default mode,\r
- * {@link com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN}.\r
- *\r
- * <li>Some locales use rounding in their currency formats to reflect the\r
- * smallest currency denomination.\r
- *\r
- * <li>In a pattern, digits '1' through '9' specify rounding, but otherwise\r
- * behave identically to digit '0'.\r
- * </ul>\r
- *\r
- * <h4>Synchronization</h4>\r
- *\r
- * <p><code>DecimalFormat</code> objects are not synchronized.  Multiple\r
- * threads should not access one formatter concurrently.\r
- *\r
- * @see          java.text.Format\r
- * @see          NumberFormat\r
- * @author       Mark Davis\r
- * @author       Alan Liu\r
- * @stable ICU 2.0\r
- */\r
-public class DecimalFormat extends NumberFormat {\r
-\r
-    /**\r
-     * Create a DecimalFormat using the default pattern and symbols\r
-     * for the default locale. This is a convenient way to obtain a\r
-     * DecimalFormat when internationalization is not the main concern.\r
-     * <p>\r
-     * To obtain standard formats for a given locale, use the factory methods\r
-     * on NumberFormat such as getNumberInstance. These factories will\r
-     * return the most appropriate sub-class of NumberFormat for a given\r
-     * locale.\r
-     * @see NumberFormat#getInstance\r
-     * @see NumberFormat#getNumberInstance\r
-     * @see NumberFormat#getCurrencyInstance\r
-     * @see NumberFormat#getPercentInstance\r
-     * @stable ICU 2.0\r
-     */\r
-    public DecimalFormat() {\r
-        // [NEW]\r
-        ULocale def = ULocale.getDefault();\r
-        String pattern = getPattern(def, 0);\r
-        // Always applyPattern after the symbols are set\r
-        this.symbols = new DecimalFormatSymbols(def);\r
-        setCurrency(Currency.getInstance(def));\r
-        applyPatternWithoutExpandAffix(pattern, false);\r
-        if (currencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT) {\r
-            currencyPluralInfo = new CurrencyPluralInfo(def);\r
-            // the exact pattern is not known until the plural count is known.\r
-            // so, no need to expand affix now.\r
-        } else {\r
-            expandAffixAdjustWidth(null);\r
-        }\r
-    }\r
-\r
-\r
-    /**\r
-     * Create a DecimalFormat from the given pattern and the symbols\r
-     * for the default locale. This is a convenient way to obtain a\r
-     * DecimalFormat when internationalization is not the main concern.\r
-     * <p>\r
-     * To obtain standard formats for a given locale, use the factory methods\r
-     * on NumberFormat such as getNumberInstance. These factories will\r
-     * return the most appropriate sub-class of NumberFormat for a given\r
-     * locale.\r
-     * @param pattern A non-localized pattern string.\r
-     * @exception IllegalArgumentException if the given pattern is invalid.\r
-     * @see NumberFormat#getInstance\r
-     * @see NumberFormat#getNumberInstance\r
-     * @see NumberFormat#getCurrencyInstance\r
-     * @see NumberFormat#getPercentInstance\r
-     * @stable ICU 2.0\r
-     */\r
-    public DecimalFormat(String pattern) {\r
-        // Always applyPattern after the symbols are set\r
-        ULocale def = ULocale.getDefault();\r
-        this.symbols = new DecimalFormatSymbols(def);\r
-        setCurrency(Currency.getInstance(def));\r
-        applyPatternWithoutExpandAffix( pattern, false );\r
-        if (currencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT) {\r
-            currencyPluralInfo = new CurrencyPluralInfo(def);\r
-        } else {\r
-            expandAffixAdjustWidth(null);\r
-        }\r
-    }\r
-\r
-\r
-    /**\r
-     * Create a DecimalFormat from the given pattern and symbols.\r
-     * Use this constructor when you need to completely customize the\r
-     * behavior of the format.\r
-     * <p>\r
-     * To obtain standard formats for a given\r
-     * locale, use the factory methods on NumberFormat such as\r
-     * getInstance or getCurrencyInstance. If you need only minor adjustments\r
-     * to a standard format, you can modify the format returned by\r
-     * a NumberFormat factory method.\r
-     * @param pattern a non-localized pattern string\r
-     * @param symbols the set of symbols to be used\r
-     * @exception IllegalArgumentException if the given pattern is invalid\r
-     * @see NumberFormat#getInstance\r
-     * @see NumberFormat#getNumberInstance\r
-     * @see NumberFormat#getCurrencyInstance\r
-     * @see NumberFormat#getPercentInstance\r
-     * @see DecimalFormatSymbols\r
-     * @stable ICU 2.0\r
-     */\r
-    public DecimalFormat(String pattern, DecimalFormatSymbols symbols) {\r
-        createFromPatternAndSymbols(pattern, symbols);\r
-    }\r
-\r
-    private void createFromPatternAndSymbols(String pattern, DecimalFormatSymbols inputSymbols) {\r
-        // Always applyPattern after the symbols are set\r
-        symbols = (DecimalFormatSymbols) inputSymbols.clone();\r
-        setCurrencyForSymbols();\r
-        applyPatternWithoutExpandAffix(pattern, false);\r
-        if (currencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT) {\r
-            currencyPluralInfo = new CurrencyPluralInfo(symbols.getLocale());\r
-        } else {\r
-            expandAffixAdjustWidth(null);\r
-        }\r
-    }\r
-\r
-\r
-    /**\r
-     * Create a DecimalFormat from the given pattern, symbols,\r
-     * information used for currency plural format, and format style.\r
-     * Use this constructor when you need to completely customize the\r
-     * behavior of the format.\r
-     * <p>\r
-     * To obtain standard formats for a given\r
-     * locale, use the factory methods on NumberFormat such as\r
-     * getInstance or getCurrencyInstance. \r
-     * <p>\r
-     * If you need only minor adjustments to a standard format, \r
-     * you can modify the format returned by\r
-     * a NumberFormat factory method using the setters.\r
-     * <p>\r
-     * If you want to completely customize a decimal format,\r
-     * using your own DecimalFormatSymbols (such as group separators) and\r
-     * your own information for currency plural formatting (such as\r
-     * plural rule and currency plural patterns), you can use this constructor.\r
-     * <p> \r
-     * @param pattern a non-localized pattern string\r
-     * @param symbols the set of symbols to be used\r
-     * @param infoInput the information used for currency plural format, \r
-     *                  including currency plural patterns and plural rules.\r
-     * @param style the decimal formatting style, \r
-     *              it is one of the following values:\r
-     *              NumberFormat.NUMBERSTYLE;\r
-     *              NumberFormat.CURRENCYSTYLE;\r
-     *              NumberFormat.PERCENTSTYLE;\r
-     *              NumberFormat.SCIENTIFICSTYLE;\r
-     *              NumberFormat.INTEGERSTYLE;\r
-     *              NumberFormat.ISOCURRENCYSTYLE;\r
-     *              NumberFormat.PLURALCURRENCYSTYLE;\r
-     * @draft ICU 4.2\r
-     * @provisional This API might change or be removed in a future release.\r
-     */\r
-    public DecimalFormat(String pattern, DecimalFormatSymbols symbols,\r
-                         CurrencyPluralInfo infoInput,\r
-                         int style) {\r
-        CurrencyPluralInfo info = infoInput;\r
-        if (style == NumberFormat.PLURALCURRENCYSTYLE) {\r
-            info = (CurrencyPluralInfo)infoInput.clone();\r
-        }\r
-        create(pattern, symbols, info, style);\r
-    }\r
-\r
-\r
-    private void create(String pattern, DecimalFormatSymbols inputSymbols,\r
-                        CurrencyPluralInfo info,\r
-                        int inputStyle) {\r
-        if (inputStyle != NumberFormat.PLURALCURRENCYSTYLE) {\r
-            createFromPatternAndSymbols(pattern, inputSymbols);\r
-        } else {\r
-            // Always applyPattern after the symbols are set\r
-            symbols = (DecimalFormatSymbols) inputSymbols.clone();\r
-            currencyPluralInfo = info;\r
-            // the pattern used in format is not fixed until formatting,\r
-            // in which, the number is known and \r
-            // will be used to pick the right pattern based on plural count.\r
-            // Here, set the pattern as the pattern of plural count == "other".\r
-            // For most locale, the patterns are probably the same for all\r
-            // plural count. If not, the right pattern need to be re-applied\r
-            // during format.\r
-            String currencyPluralPatternForOther = currencyPluralInfo.getCurrencyPluralPattern("other");\r
-            applyPatternWithoutExpandAffix(currencyPluralPatternForOther,false);\r
-            setCurrencyForSymbols();\r
-        }\r
-        style = inputStyle;\r
-    }\r
-\r
-\r
-    /*\r
-     * Create a DecimalFormat for currency plural format \r
-     * from the given pattern, symbols, and style.\r
-     */\r
-    DecimalFormat(String pattern, DecimalFormatSymbols inputSymbols, int style) {\r
-        CurrencyPluralInfo info = null;\r
-        if (style == NumberFormat.PLURALCURRENCYSTYLE) {\r
-            info = new CurrencyPluralInfo(inputSymbols.getLocale());\r
-        }\r
-        create(pattern, inputSymbols, info, style);\r
-    }\r
-\r
-    /**\r
-     * @stable ICU 2.0\r
-     */\r
-    public StringBuffer format(double number, StringBuffer result,\r
-            FieldPosition fieldPosition) {\r
-        return format(number, result, fieldPosition, false);\r
-    }\r
-    \r
-    // [Spark/CDL] The actual method to format number. If boolean value\r
-    // parseAttr == true, then attribute information will be recorded.\r
-    private StringBuffer format(double number, StringBuffer result,\r
-            FieldPosition fieldPosition, boolean parseAttr) \r
-    {\r
-        fieldPosition.setBeginIndex(0);\r
-        fieldPosition.setEndIndex(0);\r
-\r
-        if (Double.isNaN(number))\r
-        {\r
-            if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD) {\r
-                fieldPosition.setBeginIndex(result.length());\r
-            }\r
-//#if defined(FOUNDATION10) || defined(J2SE13) \r
-//#else \r
-            else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {\r
-                fieldPosition.setBeginIndex(result.length());\r
-            }\r
-//#endif \r
-\r
-            result.append(symbols.getNaN());\r
-            // [Spark/CDL] Add attribute for NaN here.\r
-            // result.append(symbols.getNaN());\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-            if (parseAttr) {\r
-                addAttribute(Field.INTEGER, result.length()\r
-                        - symbols.getNaN().length(), result.length());\r
-            }\r
-//#endif\r
-            if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD) {\r
-                fieldPosition.setEndIndex(result.length());\r
-            }\r
-//#if defined(FOUNDATION10) || defined(J2SE13) \r
-//#else \r
-            else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {\r
-                fieldPosition.setEndIndex(result.length());\r
-            }\r
-//#endif \r
-\r
-            addPadding(result, fieldPosition, 0, 0);\r
-            return result;\r
-        }\r
-\r
-        // Do this BEFORE checking to see if value is infinite or negative!\r
-        if (multiplier != 1) number *= multiplier;\r
-\r
-        /* Detecting whether a double is negative is easy with the exception of\r
-         * the value -0.0.  This is a double which has a zero mantissa (and\r
-         * exponent), but a negative sign bit.  It is semantically distinct from\r
-         * a zero with a positive sign bit, and this distinction is important\r
-         * to certain kinds of computations.  However, it's a little tricky to\r
-         * detect, since (-0.0 == 0.0) and !(-0.0 < 0.0).  How then, you may\r
-         * ask, does it behave distinctly from +0.0?  Well, 1/(-0.0) ==\r
-         * -Infinity.  Proper detection of -0.0 is needed to deal with the\r
-         * issues raised by bugs 4106658, 4106667, and 4147706.  Liu 7/6/98.\r
-         */\r
-        boolean isNegative = (number < 0.0) || (number == 0.0 && 1/number < 0.0);\r
-        if (isNegative) number = -number;\r
-\r
-        // Apply rounding after multiplier\r
-        if (roundingDouble > 0.0) {\r
-            // number = roundingDouble\r
-            //  * round(number / roundingDouble, roundingMode, isNegative);\r
-            double newNumber = round(number, roundingDouble, roundingDoubleReciprocal, roundingMode, isNegative);\r
-            if (newNumber == 0.0 && number != newNumber) isNegative = false; // if we touched it, then make zero be zero.\r
-            number = newNumber;\r
-        }\r
-\r
-        if (Double.isInfinite(number))\r
-        {\r
-            int prefixLen = appendAffix(result, isNegative, true, parseAttr);\r
-\r
-            if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD) {\r
-                fieldPosition.setBeginIndex(result.length());\r
-            }\r
-//#if defined(FOUNDATION10) || defined(J2SE13) \r
-//#else \r
-            else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {\r
-                fieldPosition.setBeginIndex(result.length());\r
-            }\r
-//#endif \r
-\r
-            // [Spark/CDL] Add attribute for infinity here.\r
-            result.append(symbols.getInfinity());\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-            if (parseAttr) {\r
-                addAttribute(Field.INTEGER, result.length()\r
-                        - symbols.getInfinity().length(), result.length());\r
-            }\r
-//#endif\r
-            if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD) {\r
-                fieldPosition.setEndIndex(result.length());\r
-            }\r
-//#if defined(FOUNDATION10) || defined(J2SE13) \r
-//#else \r
-            else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {\r
-                fieldPosition.setEndIndex(result.length());\r
-            }\r
-//#endif \r
-\r
-            int suffixLen = appendAffix(result, isNegative, false, parseAttr);\r
-\r
-            addPadding(result, fieldPosition, prefixLen, suffixLen);\r
-            return result;\r
-        }\r
-\r
-        // At this point we are guaranteed a nonnegative finite\r
-        // number.\r
-        synchronized(digitList) {\r
-            digitList.set(number, precision(false),\r
-                          !useExponentialNotation && !areSignificantDigitsUsed());\r
-            return subformat(number, result, fieldPosition, isNegative, false,\r
-                    parseAttr);\r
-        }\r
-    }\r
-    \r
-    // [NEW]\r
-    /**\r
-     * Round a double value to the nearest multiple of the given\r
-     * rounding increment, according to the given mode.  This is\r
-     * equivalent to rounding value/roundingInc to the nearest\r
-     * integer, according to the given mode, and returning that\r
-     * integer * roundingInc.\r
-     * Note this is changed from the version in 2.4, since division of doubles\r
-     * have inaccuracies. jitterbug 1871.\r
-     * @param number the absolute value of the number to be rounded\r
-     * @param roundingInc the rounding increment\r
-     * @param roundingIncReciprocal if non-zero, is the \r
-     * @param mode a BigDecimal rounding mode\r
-     * @param isNegative true if the number to be rounded is negative\r
-     * @return the absolute value of the rounded result\r
-     */\r
-    private static double round(double number, double roundingInc, \r
-            double roundingIncReciprocal, int mode, boolean isNegative) {\r
-        \r
-        double div = roundingIncReciprocal == 0.0 \r
-            ? number / roundingInc\r
-            : number * roundingIncReciprocal;\r
-        \r
-        // do the absolute cases first\r
-        \r
-        switch (mode) {\r
-        case BigDecimal.ROUND_CEILING:\r
-            div = (isNegative ? Math.floor(div + epsilon) : Math.ceil(div - epsilon));\r
-            break;\r
-        case BigDecimal.ROUND_FLOOR:\r
-            div = (isNegative ? Math.ceil(div - epsilon) : Math.floor(div + epsilon));\r
-            break;\r
-        case BigDecimal.ROUND_DOWN:\r
-            div = (Math.floor(div + epsilon));\r
-            break;\r
-        case BigDecimal.ROUND_UP:\r
-            div = (Math.ceil(div - epsilon));\r
-            break;\r
-        case BigDecimal.ROUND_UNNECESSARY:\r
-            if (div != Math.floor(div)) {\r
-                throw new ArithmeticException("Rounding necessary");\r
-            }\r
-            return number;\r
-        default:\r
-            \r
-            // Handle complex cases, where the choice depends on the closer value.\r
-            \r
-            // We figure out the distances to the two possible values, ceiling and floor.\r
-            // We then go for the diff that is smaller.\r
-            // Only if they are equal does the mode matter.\r
-\r
-            double ceil = Math.ceil(div);\r
-            double ceildiff = ceil - div; // (ceil * roundingInc) - number;\r
-            double floor = Math.floor(div);\r
-            double floordiff = div - floor; // number - (floor * roundingInc);\r
-            \r
-            // Note that the diff values were those mapped back to the "normal" space\r
-            // by using the roundingInc. I don't have access to the original author of the code\r
-            // but suspect that that was to produce better result in edge cases because of machine\r
-            // precision, rather than simply using the difference between, say, ceil and div.\r
-            // However, it didn't work in all cases. Am trying instead using an epsilon value.\r
-            \r
-            switch (mode) {\r
-            case BigDecimal.ROUND_HALF_EVEN:\r
-                // We should be able to just return Math.rint(a), but this\r
-                // doesn't work in some VMs.\r
-                // if one is smaller than the other, take the corresponding side\r
-                if (floordiff + epsilon < ceildiff) {\r
-                        div = floor;\r
-                    } else if (ceildiff + epsilon < floordiff) {\r
-                        div = ceil;\r
-                } else { // they are equal, so we want to round to whichever is even\r
-                    double testFloor = floor / 2;\r
-                    div = (testFloor == Math.floor(testFloor)) ? floor : ceil;\r
-                }\r
-                break;\r
-            case BigDecimal.ROUND_HALF_DOWN:\r
-                div = ((floordiff <= ceildiff + epsilon) ? floor : ceil);\r
-                break;\r
-            case BigDecimal.ROUND_HALF_UP:\r
-                div = ((ceildiff <= floordiff + epsilon) ? ceil : floor);\r
-                break;\r
-            default:\r
-                throw new IllegalArgumentException("Invalid rounding mode: " + mode);\r
-            }\r
-        }\r
-        number = roundingIncReciprocal == 0.0\r
-            ? div * roundingInc\r
-            : div / roundingIncReciprocal;\r
-        return number;\r
-    }\r
-    private static double epsilon = 0.00000000001;\r
-\r
-    /**\r
-     * @stable ICU 2.0\r
-     */\r
-    // [Spark/CDL] Delegate to format_long_StringBuffer_FieldPosition_boolean\r
-    public StringBuffer format(long number, StringBuffer result,\r
-            FieldPosition fieldPosition) {\r
-        return format(number, result, fieldPosition, false);\r
-    }\r
-\r
-    private StringBuffer format(long number, StringBuffer result,\r
-            FieldPosition fieldPosition, boolean parseAttr) \r
-    {\r
-        fieldPosition.setBeginIndex(0);\r
-        fieldPosition.setEndIndex(0);\r
-\r
-        // If we are to do rounding, we need to move into the BigDecimal\r
-        // domain in order to do divide/multiply correctly.\r
-        // [NEW]\r
-        if (roundingIncrementICU != null) {\r
-            return format(BigDecimal.valueOf(number), result, fieldPosition);\r
-        }\r
-\r
-        boolean isNegative = (number < 0);\r
-        if (isNegative) number = -number;\r
-\r
-        // In general, long values always represent real finite numbers, so\r
-        // we don't have to check for +/- Infinity or NaN.  However, there\r
-        // is one case we have to be careful of:  The multiplier can push\r
-        // a number near MIN_VALUE or MAX_VALUE outside the legal range.  We\r
-        // check for this before multiplying, and if it happens we use BigInteger\r
-        // instead.\r
-        // [NEW]\r
-        if (multiplier != 1) {\r
-            boolean tooBig = false;\r
-            if (number < 0) { // This can only happen if number == Long.MIN_VALUE\r
-                long cutoff = Long.MIN_VALUE / multiplier;\r
-                tooBig = (number <= cutoff); // number == cutoff can only happen if multiplier == -1\r
-            } else {\r
-                long cutoff = Long.MAX_VALUE / multiplier;\r
-                tooBig = (number > cutoff);\r
-            }\r
-            if (tooBig) {\r
-                // [Spark/CDL] Use\r
-                // format_BigInteger_StringBuffer_FieldPosition_boolean instead\r
-                // parseAttr is used to judge whether to synthesize attributes.\r
-                return format(\r
-                        BigInteger.valueOf(isNegative ? -number : number),\r
-                        result, fieldPosition, parseAttr);\r
-            }\r
-        }\r
-\r
-        number *= multiplier;\r
-        synchronized(digitList) {\r
-            digitList.set(number, precision(true));\r
-            return subformat(number, result, fieldPosition, isNegative, true, parseAttr);\r
-        }\r
-    }\r
-\r
-    // [NEW]\r
-    /**\r
-     * Format a BigInteger number.\r
-     * \r
-     * @stable ICU 2.0\r
-     */\r
-    public StringBuffer format(BigInteger number, StringBuffer result,\r
-            FieldPosition fieldPosition) {\r
-        return format(number, result, fieldPosition, false);\r
-    }\r
-\r
-    // [Spark/CDL] \r
-    private StringBuffer format(BigInteger number, StringBuffer result,\r
-            FieldPosition fieldPosition, boolean parseAttr) {\r
-        // If we are to do rounding, we need to move into the BigDecimal\r
-        // domain in order to do divide/multiply correctly.\r
-        if (roundingIncrementICU != null) {\r
-            return format(new BigDecimal(number), result, fieldPosition);\r
-        }\r
-\r
-        if (multiplier != 1) {\r
-            number = number.multiply(BigInteger.valueOf(multiplier));\r
-        }\r
-\r
-        // At this point we are guaranteed a nonnegative finite\r
-        // number.\r
-        synchronized(digitList) {\r
-            digitList.set(number, precision(true));\r
-            return subformat(number.intValue(), result, fieldPosition, number.signum() < 0, true, parseAttr);\r
-        }\r
-    }\r
-\r
-//#if defined(FOUNDATION10)\r
-//#else\r
-    // [NEW]\r
-    /**\r
-     * Format a BigDecimal number.\r
-     * @stable ICU 2.0\r
-     */\r
-    public StringBuffer format(java.math.BigDecimal number, StringBuffer result,\r
-                               FieldPosition fieldPosition) {\r
-        return format(number, result, fieldPosition, false);\r
-    }\r
-    \r
-    private StringBuffer format(java.math.BigDecimal number,\r
-            StringBuffer result, FieldPosition fieldPosition, boolean parseAttr) {\r
-        if (multiplier != 1) {\r
-            number = number.multiply(java.math.BigDecimal.valueOf(multiplier));\r
-        }\r
-\r
-        if (roundingIncrement != null) {\r
-            number = number.divide(roundingIncrement, 0, roundingMode)\r
-                    .multiply(roundingIncrement);\r
-        }\r
-\r
-        synchronized(digitList) {\r
-            digitList.set(number, precision(false),\r
-                          !useExponentialNotation && !areSignificantDigitsUsed());\r
-            return subformat(number.doubleValue(), result, fieldPosition, number.signum() < 0, false, parseAttr);\r
-        }        \r
-    }\r
-//#endif\r
-    \r
-    // [NEW]\r
-    /**\r
-     * Format a BigDecimal number.\r
-     * @stable ICU 2.0\r
-     */\r
-    public StringBuffer format(BigDecimal number, StringBuffer result,\r
-                               FieldPosition fieldPosition) {\r
-        /* This method is just a copy of the corresponding java.math.BigDecimal\r
-         * method for now.  It isn't very efficient since it must create a\r
-         * conversion object to do math on the rounding increment.  In the\r
-         * future we may try to clean this up, or even better, limit our support\r
-         * to just one flavor of BigDecimal.\r
-         */\r
-        if (multiplier != 1) {\r
-            number = number.multiply(BigDecimal.valueOf(multiplier), mathContext);\r
-        }\r
-\r
-        if (roundingIncrementICU != null) {\r
-            number = number.divide(roundingIncrementICU, 0, roundingMode)\r
-                .multiply(roundingIncrementICU, mathContext);\r
-        }\r
-\r
-        synchronized(digitList) {\r
-            digitList.set(number, precision(false),\r
-                          !useExponentialNotation && !areSignificantDigitsUsed());\r
-            return subformat(number.doubleValue(), result, fieldPosition, number.signum() < 0, false, false);\r
-        }        \r
-    }\r
-\r
-    /**\r
-     * Return true if a grouping separator belongs at the given\r
-     * position, based on whether grouping is in use and the values of\r
-     * the primary and secondary grouping interval.\r
-     * @param pos the number of integer digits to the right of\r
-     * the current position.  Zero indicates the position after the\r
-     * rightmost integer digit.\r
-     * @return true if a grouping character belongs at the current\r
-     * position.\r
-     */\r
-    private boolean isGroupingPosition(int pos) {\r
-        boolean result = false;\r
-        if (isGroupingUsed() && (pos > 0) && (groupingSize > 0)) {\r
-            if ((groupingSize2 > 0) && (pos > groupingSize)) {\r
-                result = ((pos - groupingSize) % groupingSize2) == 0;\r
-            } else {\r
-                result = pos % groupingSize == 0;\r
-            }\r
-        }\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * Return the number of fraction digits to display, or the total\r
-     * number of digits for significant digit formats and exponential\r
-     * formats.\r
-     */\r
-    private int precision(boolean isIntegral) {\r
-        if (areSignificantDigitsUsed()) {\r
-            return getMaximumSignificantDigits();\r
-        } else if (useExponentialNotation) {\r
-            return getMinimumIntegerDigits() + getMaximumFractionDigits();\r
-        } else {\r
-            return isIntegral ? 0 : getMaximumFractionDigits();\r
-        }\r
-    }\r
-\r
-    private StringBuffer subformat(int number, StringBuffer result, \r
-                                   FieldPosition fieldPosition,\r
-                                   boolean isNegative, boolean isInteger, \r
-                                   boolean parseAttr) {\r
-        if (currencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT) { \r
-            return subformat(currencyPluralInfo.select(number), result, fieldPosition,\r
-                             isNegative, isInteger, parseAttr);\r
-        } else {\r
-            return subformat(result, fieldPosition, isNegative, isInteger, parseAttr);\r
-        }\r
-    }\r
-\r
-    private StringBuffer subformat(double number, StringBuffer result, \r
-                                   FieldPosition fieldPosition,\r
-                                   boolean isNegative, boolean isInteger,\r
-                                   boolean parseAttr) {\r
-        if (currencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT) { \r
-            return subformat(currencyPluralInfo.select(number), result, fieldPosition,\r
-                             isNegative, isInteger, parseAttr);\r
-        } else {\r
-            return subformat(result, fieldPosition, isNegative, isInteger, parseAttr);\r
-        }\r
-    }\r
-\r
-    private StringBuffer subformat(String pluralCount, \r
-            StringBuffer result,\r
-            FieldPosition fieldPosition, boolean isNegative, boolean isInteger,\r
-            boolean parseAttr) \r
-    {\r
-        // There are 2 ways to activate currency plural format:\r
-        // by applying a pattern with 3 currency sign directly,\r
-        // or by instantiate a decimal formatter using PLURALCURRENCYSTYLE.\r
-        // For both cases, the number of currency sign in the pattern is 3.\r
-        // Even if the number of currency sign in the pattern is 3, \r
-        // it does not mean we need to reset the pattern.\r
-        // For 1st case, we do not need to reset pattern.\r
-        // For 2nd case, we might need to reset pattern,\r
-        // if the default pattern (corresponding to plural count 'other')\r
-        // we use is different from the pattern based on 'pluralCount'.\r
-        // \r
-        // style is only valid when decimal formatter is constructed through\r
-        // DecimalFormat(pattern, symbol, style)\r
-        if (style == NumberFormat.PLURALCURRENCYSTYLE) {\r
-            // May need to reset pattern if the style is PLURALCURRENCYSTYLE.\r
-            String currencyPluralPattern = currencyPluralInfo.getCurrencyPluralPattern(pluralCount);\r
-            if (formatPattern.equals(currencyPluralPattern) == false) {\r
-                applyPatternWithoutExpandAffix(currencyPluralPattern, false);\r
-            }\r
-        }\r
-        // Expand the affix to the right name according to\r
-        // the plural rule.\r
-        // This is only used for currency plural formatting.\r
-        // Currency plural name is not a fixed static one,\r
-        // it is a dynamic name based on the currency plural count.\r
-        // So, the affixes need to be expanded here.\r
-        // For other cases, the affix is a static one based on pattern alone,\r
-        // and it is already expanded during applying pattern,\r
-        // or setDecimalFormatSymbols, or setCurrency.\r
-        expandAffixAdjustWidth(pluralCount);\r
-        return subformat(result, fieldPosition, isNegative, isInteger, parseAttr);\r
-    }\r
-\r
-    /**\r
-     * Complete the formatting of a finite number.  On entry, the digitList must\r
-     * be filled in with the correct digits.\r
-     */\r
-    private StringBuffer subformat(StringBuffer result,\r
-            FieldPosition fieldPosition, boolean isNegative, boolean isInteger,\r
-            boolean parseAttr) \r
-    {\r
-        // NOTE: This isn't required anymore because DigitList takes care of this.\r
-        //\r
-        //  // The negative of the exponent represents the number of leading\r
-        //  // zeros between the decimal and the first non-zero digit, for\r
-        //  // a value < 0.1 (e.g., for 0.00123, -fExponent == 2).  If this\r
-        //  // is more than the maximum fraction digits, then we have an underflow\r
-        //  // for the printed representation.  We recognize this here and set\r
-        //  // the DigitList representation to zero in this situation.\r
-        //\r
-        //  if (-digitList.decimalAt >= getMaximumFractionDigits())\r
-        //  {\r
-        //      digitList.count = 0;\r
-        //  }\r
-\r
-        int i;\r
-        char zero = symbols.getZeroDigit();\r
-        int zeroDelta = zero - '0'; // '0' is the DigitList representation of zero\r
-        char grouping = currencySignCount > 0 ?\r
-                    symbols.getMonetaryGroupingSeparator() :\r
-                    symbols.getGroupingSeparator();\r
-        char decimal =  currencySignCount > 0 ?\r
-            symbols.getMonetaryDecimalSeparator() :\r
-            symbols.getDecimalSeparator();\r
-        boolean useSigDig = areSignificantDigitsUsed();\r
-        int maxIntDig = getMaximumIntegerDigits();\r
-        int minIntDig = getMinimumIntegerDigits();\r
-\r
-        /* Per bug 4147706, DecimalFormat must respect the sign of numbers which\r
-         * format as zero.  This allows sensible computations and preserves\r
-         * relations such as signum(1/x) = signum(x), where x is +Infinity or\r
-         * -Infinity.  Prior to this fix, we always formatted zero values as if\r
-         * they were positive.  Liu 7/6/98.\r
-         */\r
-        if (digitList.isZero())\r
-        {\r
-            digitList.decimalAt = 0; // Normalize\r
-        }\r
-\r
-        int prefixLen = appendAffix(result, isNegative, true, parseAttr);\r
-\r
-        if (useExponentialNotation)\r
-        {\r
-            // Record field information for caller.\r
-            if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD) {\r
-                fieldPosition.setBeginIndex(result.length());\r
-                fieldPosition.setEndIndex(-1);\r
-            } else if (fieldPosition.getField() == NumberFormat.FRACTION_FIELD) {\r
-                fieldPosition.setBeginIndex(-1);\r
-            }\r
-//#if defined(FOUNDATION10) || defined(J2SE13) \r
-//#else \r
-            else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {\r
-                fieldPosition.setBeginIndex(result.length());\r
-                fieldPosition.setEndIndex(-1);\r
-            } else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.FRACTION) {\r
-                fieldPosition.setBeginIndex(-1);\r
-            } \r
-//#endif \r
-\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-            // [Spark/CDL]\r
-            // the begin index of integer part\r
-            // the end index of integer part\r
-            // the begin index of fractional part\r
-            int intBegin = result.length();\r
-            int intEnd = -1;\r
-            int fracBegin = -1;\r
-//#endif\r
-\r
-            int minFracDig = 0;\r
-            if (useSigDig) {\r
-                maxIntDig = minIntDig = 1;\r
-                minFracDig = getMinimumSignificantDigits() - 1;\r
-            } else {\r
-                minFracDig = getMinimumFractionDigits();\r
-                if (maxIntDig > MAX_SCIENTIFIC_INTEGER_DIGITS) {\r
-                    maxIntDig = 1;\r
-                    if (maxIntDig < minIntDig) {\r
-                        maxIntDig = minIntDig;\r
-                    }\r
-                }\r
-                if (maxIntDig > minIntDig) {\r
-                    minIntDig = 1;\r
-                }\r
-            }            \r
-\r
-            // Minimum integer digits are handled in exponential format by\r
-            // adjusting the exponent.  For example, 0.01234 with 3 minimum\r
-            // integer digits is "123.4E-4".\r
-\r
-            // Maximum integer digits are interpreted as indicating the\r
-            // repeating range.  This is useful for engineering notation, in\r
-            // which the exponent is restricted to a multiple of 3.  For\r
-            // example, 0.01234 with 3 maximum integer digits is "12.34e-3".\r
-            // If maximum integer digits are defined and are larger than\r
-            // minimum integer digits, then minimum integer digits are\r
-            // ignored.\r
-\r
-            int exponent = digitList.decimalAt;\r
-            if (maxIntDig > 1 && maxIntDig != minIntDig) {\r
-                // A exponent increment is defined; adjust to it.\r
-                exponent = (exponent > 0) ? (exponent - 1) / maxIntDig\r
-                                          : (exponent / maxIntDig) - 1;\r
-                exponent *= maxIntDig;\r
-            } else {\r
-                // No exponent increment is defined; use minimum integer digits.\r
-                // If none is specified, as in "#E0", generate 1 integer digit.\r
-                exponent -= (minIntDig > 0 || minFracDig > 0)\r
-                    ? minIntDig : 1;\r
-            }\r
-\r
-            // We now output a minimum number of digits, and more if there\r
-            // are more digits, up to the maximum number of digits.  We\r
-            // place the decimal point after the "integer" digits, which\r
-            // are the first (decimalAt - exponent) digits.\r
-            int minimumDigits = minIntDig + minFracDig;\r
-            // The number of integer digits is handled specially if the number\r
-            // is zero, since then there may be no digits.\r
-            int integerDigits = digitList.isZero() ? minIntDig :\r
-                digitList.decimalAt - exponent;\r
-            int totalDigits = digitList.count;\r
-            if (minimumDigits > totalDigits) totalDigits = minimumDigits;\r
-            if (integerDigits > totalDigits) totalDigits = integerDigits;\r
-\r
-            for (i=0; i<totalDigits; ++i)\r
-            {\r
-                if (i == integerDigits)\r
-                {\r
-                    // Record field information for caller.\r
-                    if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD) {\r
-                        fieldPosition.setEndIndex(result.length());\r
-                    }\r
-//#if defined(FOUNDATION10) || defined(J2SE13) \r
-//#else \r
-                    else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {\r
-                        fieldPosition.setEndIndex(result.length());\r
-                    }\r
-//#endif \r
-\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-                    // [Spark/CDL] Add attribute for integer part\r
-                    if (parseAttr) {\r
-                        intEnd = result.length();\r
-                        addAttribute(Field.INTEGER, intBegin, result.length());\r
-                    }\r
-//#endif\r
-                    result.append(decimal);\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-                    // [Spark/CDL] Add attribute for decimal separator\r
-                    if (parseAttr) {\r
-                        // Length of decimal separator is 1.\r
-                        int decimalSeparatorBegin = result.length() - 1;\r
-                        addAttribute(Field.DECIMAL_SEPARATOR,\r
-                                decimalSeparatorBegin, result.length());\r
-                            fracBegin = result.length();\r
-                    }\r
-//#endif\r
-                    // Record field information for caller.\r
-                    if (fieldPosition.getField() == NumberFormat.FRACTION_FIELD) {\r
-                        fieldPosition.setBeginIndex(result.length());\r
-                    }\r
-//#if defined(FOUNDATION10) || defined(J2SE13) \r
-//#else \r
-                    else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.FRACTION) {\r
-                        fieldPosition.setBeginIndex(result.length());\r
-                    }\r
-//#endif \r
-\r
-                }\r
-                result.append((i < digitList.count) ?\r
-                          (char)(digitList.digits[i] + zeroDelta) :\r
-                          zero);\r
-            }\r
-            \r
-            //For ICU compatibility and format 0 to 0E0 with pattern "#E0" [Richard/GCL]\r
-            if (digitList.isZero() && (totalDigits ==0)) {\r
-                result.append(zero);\r
-            }\r
-\r
-            // Record field information\r
-            if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD) {\r
-                if (fieldPosition.getEndIndex() < 0) {\r
-                    fieldPosition.setEndIndex(result.length());\r
-                }\r
-            } else if (fieldPosition.getField() == NumberFormat.FRACTION_FIELD) {\r
-                if (fieldPosition.getBeginIndex() < 0) {\r
-                    fieldPosition.setBeginIndex(result.length());\r
-                }\r
-                fieldPosition.setEndIndex(result.length());\r
-            }\r
-//#if defined(FOUNDATION10) || defined(J2SE13) \r
-//#else \r
-            else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {\r
-                if (fieldPosition.getEndIndex() < 0) {\r
-                    fieldPosition.setEndIndex(result.length());\r
-                }\r
-            } else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.FRACTION) {\r
-                if (fieldPosition.getBeginIndex() < 0) {\r
-                    fieldPosition.setBeginIndex(result.length());\r
-                }\r
-                fieldPosition.setEndIndex(result.length());\r
-            }\r
-//#endif \r
-\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-            // [Spark/CDL] Calcuate the end index of integer part and fractional\r
-            // part if they are not properly processed yet.\r
-            if (parseAttr) {\r
-                if (intEnd < 0) {\r
-                    addAttribute(Field.INTEGER, intBegin, result.length());\r
-                }\r
-                if (fracBegin > 0) {\r
-                    addAttribute(Field.FRACTION, fracBegin, result.length());\r
-                }\r
-            }\r
-//#endif\r
-\r
-            // The exponent is output using the pattern-specified minimum\r
-            // exponent digits.  There is no maximum limit to the exponent\r
-            // digits, since truncating the exponent would result in an\r
-            // unacceptable inaccuracy.\r
-            result.append(symbols.getExponentSeparator());\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-            // [Spark/CDL] For exponent symbol, add an attribute.\r
-            if (parseAttr) {\r
-                addAttribute(Field.EXPONENT_SYMBOL, result.length()\r
-                        - symbols.getExponentSeparator().length(), result\r
-                        .length());\r
-            }\r
-//#endif\r
-            // For zero values, we force the exponent to zero.  We\r
-            // must do this here, and not earlier, because the value\r
-            // is used to determine integer digit count above.\r
-            if (digitList.isZero()) exponent = 0;\r
-\r
-            boolean negativeExponent = exponent < 0;\r
-            if (negativeExponent) {\r
-                exponent = -exponent;\r
-                result.append(symbols.getMinusSign());\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-                // [Spark/CDL] If exponent has sign, then add an exponent sign\r
-                // attribute.\r
-                if (parseAttr) {\r
-                    // Length of exponent sign is 1.\r
-                    addAttribute(Field.EXPONENT_SIGN, result.length() - 1,\r
-                            result.length());\r
-                }\r
-//#endif\r
-            } else if (exponentSignAlwaysShown) {\r
-                result.append(symbols.getPlusSign());\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-                // [Spark/CDL] Add an plus sign attribute.\r
-                if (parseAttr) {\r
-                    // Length of exponent sign is 1.\r
-                    int expSignBegin = result.length() - 1;\r
-                    addAttribute(Field.EXPONENT_SIGN, expSignBegin, result\r
-                            .length());\r
-                }\r
-//#endif\r
-            }\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-            int expBegin = result.length();\r
-//#endif\r
-            digitList.set(exponent);\r
-            {\r
-                int expDig = minExponentDigits;\r
-                if (useExponentialNotation && expDig < 1) {\r
-                    expDig = 1;\r
-                }\r
-                for (i=digitList.decimalAt; i<expDig; ++i) result.append(zero);\r
-            }\r
-            for (i=0; i<digitList.decimalAt; ++i)\r
-            {\r
-                result.append((i < digitList.count) ?\r
-                          (char)(digitList.digits[i] + zeroDelta) : zero);\r
-            }\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-            // [Spark/CDL] Add attribute for exponent part.\r
-            if (parseAttr) {\r
-                addAttribute(Field.EXPONENT, expBegin, result.length());\r
-            }\r
-//#endif\r
-        }\r
-        else\r
-        {\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-            // [Spark/CDL] Record the integer start index.\r
-            int intBegin = result.length();\r
-//#endif\r
-            // Record field information for caller.\r
-            if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD) {\r
-                fieldPosition.setBeginIndex(result.length());\r
-            }\r
-//#if defined(FOUNDATION10) || defined(J2SE13) \r
-//#else \r
-            else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {\r
-                fieldPosition.setBeginIndex(result.length());\r
-            }\r
-//#endif \r
-\r
-            int sigCount = 0;\r
-            int minSigDig = getMinimumSignificantDigits();\r
-            int maxSigDig = getMaximumSignificantDigits();\r
-            if (!useSigDig) {\r
-                minSigDig = 0;\r
-                maxSigDig = Integer.MAX_VALUE;\r
-            }\r
-\r
-            // Output the integer portion.  Here 'count' is the total\r
-            // number of integer digits we will display, including both\r
-            // leading zeros required to satisfy getMinimumIntegerDigits,\r
-            // and actual digits present in the number.\r
-            int count = useSigDig ?\r
-                Math.max(1, digitList.decimalAt) : minIntDig;\r
-            if (digitList.decimalAt > 0 && count < digitList.decimalAt) {\r
-                count = digitList.decimalAt;\r
-            }\r
-\r
-            // Handle the case where getMaximumIntegerDigits() is smaller\r
-            // than the real number of integer digits.  If this is so, we\r
-            // output the least significant max integer digits.  For example,\r
-            // the value 1997 printed with 2 max integer digits is just "97".\r
-\r
-            int digitIndex = 0; // Index into digitList.fDigits[]\r
-            if (count > maxIntDig && maxIntDig >= 0) {\r
-                count = maxIntDig;\r
-                digitIndex = digitList.decimalAt - count;\r
-            }\r
-\r
-            int sizeBeforeIntegerPart = result.length();\r
-            for (i=count-1; i>=0; --i)\r
-            {\r
-                if (i < digitList.decimalAt && digitIndex < digitList.count &&\r
-                    sigCount < maxSigDig) {\r
-                    // Output a real digit\r
-                    byte d = digitList.digits[digitIndex++];\r
-                    result.append((char)(d + zeroDelta));\r
-                    ++sigCount;\r
-                }\r
-                else\r
-                {\r
-                    // Output a zero (leading or trailing)\r
-                    result.append(zero);\r
-                    if (sigCount > 0) {\r
-                        ++sigCount;\r
-                    }\r
-                }\r
-\r
-                // Output grouping separator if necessary.\r
-                if (isGroupingPosition(i)) {\r
-                    result.append(grouping);\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-                    // [Spark/CDL] Add grouping separator attribute here.\r
-                    if (parseAttr) {\r
-                        // Length of grouping separator is 1.\r
-                        addAttribute(Field.GROUPING_SEPARATOR,\r
-                                result.length() - 1, result.length());\r
-                    }\r
-//#endif\r
-                }\r
-            }\r
-\r
-            // Record field information for caller.\r
-            if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD) {\r
-                fieldPosition.setEndIndex(result.length());\r
-            }\r
-//#if defined(FOUNDATION10) || defined(J2SE13) \r
-//#else \r
-            else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {\r
-                fieldPosition.setEndIndex(result.length());\r
-            }\r
-//#endif \r
-\r
-            // Determine whether or not there are any printable fractional\r
-            // digits.  If we've used up the digits we know there aren't.\r
-            boolean fractionPresent = (!isInteger && digitIndex < digitList.count) ||\r
-                (useSigDig ? (sigCount < minSigDig) : (getMinimumFractionDigits() > 0));\r
-\r
-            // If there is no fraction present, and we haven't printed any\r
-            // integer digits, then print a zero.  Otherwise we won't print\r
-            // _any_ digits, and we won't be able to parse this string.\r
-            if (!fractionPresent && result.length() == sizeBeforeIntegerPart)\r
-                result.append(zero);\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-            // [Spark/CDL] Add attribute for integer part.\r
-            if (parseAttr) {\r
-                addAttribute(Field.INTEGER, intBegin, result.length());\r
-            }\r
-//#endif\r
-            // Output the decimal separator if we always do so.\r
-            if (decimalSeparatorAlwaysShown || fractionPresent)\r
-            {\r
-                result.append(decimal);\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-                // [Spark/CDL] Add attribute for decimal separator\r
-                if (parseAttr) {\r
-                    addAttribute(Field.DECIMAL_SEPARATOR, result.length() - 1,\r
-                            result.length());\r
-                }\r
-//#endif\r
-            }\r
-\r
-            // Record field information for caller.\r
-            if (fieldPosition.getField() == NumberFormat.FRACTION_FIELD) {\r
-                fieldPosition.setBeginIndex(result.length());\r
-            }\r
-//#if defined(FOUNDATION10) || defined(J2SE13) \r
-//#else \r
-            else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.FRACTION) {\r
-                fieldPosition.setBeginIndex(result.length());\r
-            }\r
-//#endif \r
-\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-            // [Spark/CDL] Record the begin index of fraction part.\r
-            int fracBegin = result.length();\r
-//#endif\r
-\r
-            count = useSigDig ? Integer.MAX_VALUE : getMaximumFractionDigits();\r
-            if (useSigDig && (sigCount == maxSigDig ||\r
-                              (sigCount >= minSigDig && digitIndex == digitList.count))) {\r
-                count = 0;   \r
-            }\r
-            for (i=0; i < count; ++i) {\r
-                // Here is where we escape from the loop.  We escape\r
-                // if we've output the maximum fraction digits\r
-                // (specified in the for expression above).  We also\r
-                // stop when we've output the minimum digits and\r
-                // either: we have an integer, so there is no\r
-                // fractional stuff to display, or we're out of\r
-                // significant digits.\r
-                if (!useSigDig && i >= getMinimumFractionDigits() &&\r
-                    (isInteger || digitIndex >= digitList.count)) {\r
-                    break;\r
-                }\r
-\r
-                // Output leading fractional zeros.  These are zeros\r
-                // that come after the decimal but before any\r
-                // significant digits.  These are only output if\r
-                // abs(number being formatted) < 1.0.\r
-                if (-1-i > (digitList.decimalAt-1)) {\r
-                    result.append(zero);\r
-                    continue;\r
-                }\r
-\r
-                // Output a digit, if we have any precision left, or a\r
-                // zero if we don't.  We don't want to output noise digits.\r
-                if (!isInteger && digitIndex < digitList.count) {\r
-                    result.append((char)(digitList.digits[digitIndex++] + zeroDelta));\r
-                } else {\r
-                    result.append(zero);\r
-                }\r
-\r
-                // If we reach the maximum number of significant\r
-                // digits, or if we output all the real digits and\r
-                // reach the minimum, then we are done.\r
-                ++sigCount;\r
-                if (useSigDig &&\r
-                    (sigCount == maxSigDig ||\r
-                     (digitIndex == digitList.count && sigCount >= minSigDig))) {\r
-                    break;\r
-                }\r
-            }\r
-\r
-            // Record field information for caller.\r
-            if (fieldPosition.getField() == NumberFormat.FRACTION_FIELD) {\r
-                fieldPosition.setEndIndex(result.length());\r
-            }\r
-//#if defined(FOUNDATION10) || defined(J2SE13) \r
-//#else \r
-            else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.FRACTION) {\r
-                fieldPosition.setEndIndex(result.length());\r
-            }\r
-//#endif \r
-\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-            // [Spark/CDL] Add attribute information if necessary.\r
-            if (parseAttr && (decimalSeparatorAlwaysShown || fractionPresent)) {\r
-                addAttribute(Field.FRACTION, fracBegin, result.length());\r
-            }\r
-//#endif\r
-        }\r
-\r
-        int suffixLen = appendAffix(result, isNegative, false, parseAttr);\r
-\r
-        // [NEW]\r
-        addPadding(result, fieldPosition, prefixLen, suffixLen);\r
-        return result;\r
-    }\r
-\r
-    // [NEW]\r
-    private final void addPadding(StringBuffer result, FieldPosition fieldPosition,\r
-                                  int prefixLen, int suffixLen) {\r
-        if (formatWidth > 0) {\r
-            int len = formatWidth - result.length();\r
-            if (len > 0) {\r
-                char[] padding = new char[len];\r
-                for (int i=0; i<len; ++i) {\r
-                    padding[i] = pad;\r
-                }\r
-                switch (padPosition) {\r
-                case PAD_AFTER_PREFIX:\r
-                    result.insert(prefixLen, padding);\r
-                    break;\r
-                case PAD_BEFORE_PREFIX:\r
-                    result.insert(0, padding);\r
-                    break;\r
-                case PAD_BEFORE_SUFFIX:\r
-                    result.insert(result.length() - suffixLen, padding);\r
-                    break;\r
-                case PAD_AFTER_SUFFIX:\r
-                    result.append(padding);\r
-                    break;\r
-                }\r
-                if (padPosition == PAD_BEFORE_PREFIX ||\r
-                    padPosition == PAD_AFTER_PREFIX) {\r
-                    fieldPosition.setBeginIndex(fieldPosition.getBeginIndex() + len);\r
-                    fieldPosition.setEndIndex(fieldPosition.getEndIndex() + len);\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-    // [CHANGED]\r
-    /**\r
-     * Parse the given string, returning a <code>Number</code> object to\r
-     * represent the parsed value.  <code>Double</code> objects are returned to\r
-     * represent non-integral values which cannot be stored in a\r
-     * <code>BigDecimal</code>.  These are <code>NaN</code>, infinity,\r
-     * -infinity, and -0.0.  If {@link #isParseBigDecimal()} is false (the\r
-     * default), all other values are returned as <code>Long</code>,\r
-     * <code>BigInteger</code>, or <code>BigDecimal</code> values,\r
-     * in that order of preference. If {@link #isParseBigDecimal()} is true,\r
-     * all other values are returned as <code>BigDecimal</code> valuse.\r
-     * If the parse fails, null is returned.\r
-     * @param text the string to be parsed\r
-     * @param parsePosition defines the position where parsing is to begin,\r
-     * and upon return, the position where parsing left off.  If the position\r
-     * has not changed upon return, then parsing failed.\r
-     * @return a <code>Number</code> object with the parsed value or\r
-     * <code>null</code> if the parse failed\r
-     * @stable ICU 2.0\r
-     */\r
-    public Number parse(String text, ParsePosition parsePosition) {\r
-       return (Number) parse(text, parsePosition, false);\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
-        return (CurrencyAmount) parse(text, pos, true);\r
-    }\r
-\r
-    /**\r
-     * Parses the given text as either a Number or a CurrencyAmount.\r
-     * @param text the string to parse\r
-     * @param parsePosition input-output position; on input, the\r
-     * position within text to match; must have 0 <= pos.getIndex() <\r
-     * text.length(); on output, the position after the last matched\r
-     * character. If the parse fails, the position in unchanged upon\r
-     * output.\r
-     * @param parseCurrency if true, a CurrencyAmount is parsed and\r
-     * returned; otherwise a Number is parsed and returned\r
-     * @return a Number or CurrencyAmount or null\r
-     */\r
-    private Object parse(String text, ParsePosition parsePosition, boolean parseCurrency) {\r
-        int backup;\r
-        int i = backup = parsePosition.getIndex();\r
-\r
-        // Handle NaN as a special case:\r
-\r
-        // Skip padding characters, if around prefix\r
-        if (formatWidth > 0 && (padPosition == PAD_BEFORE_PREFIX ||\r
-                                padPosition == PAD_AFTER_PREFIX)) {\r
-            i = skipPadding(text, i);\r
-        }\r
-        if (text.regionMatches(i, symbols.getNaN(),\r
-                               0, symbols.getNaN().length())) {\r
-            i += symbols.getNaN().length();\r
-            // Skip padding characters, if around suffix\r
-            if (formatWidth > 0 && (padPosition == PAD_BEFORE_SUFFIX ||\r
-                                    padPosition == PAD_AFTER_SUFFIX)) {\r
-                i = skipPadding(text, i);\r
-            }\r
-            parsePosition.setIndex(i);\r
-            return new Double(Double.NaN);\r
-        }\r
-\r
-        // NaN parse failed; start over\r
-        i = backup;\r
-\r
-        boolean[] status = new boolean[STATUS_LENGTH];\r
-        Currency[] currency = parseCurrency ? new Currency[1] : null;\r
-        if (currencySignCount > 0) {\r
-            if (!parseForCurrency(text, parsePosition, parseCurrency, \r
-                                  currency, status)) {\r
-                return null;\r
-            }\r
-        } else {\r
-            if (!subparse(text, parsePosition, digitList, false, status, \r
-                          currency, negPrefixPattern, negSuffixPattern,\r
-                          posPrefixPattern, posSuffixPattern, Currency.SYMBOL_NAME)) {\r
-                parsePosition.setIndex(backup);\r
-                return null;\r
-            }\r
-        }\r
-\r
-        Number n = null;\r
-\r
-        // Handle infinity\r
-        if (status[STATUS_INFINITE]) {\r
-            n = new Double(status[STATUS_POSITIVE]\r
-                           ? Double.POSITIVE_INFINITY\r
-                           : Double.NEGATIVE_INFINITY);\r
-        }\r
-\r
-        // Handle underflow\r
-        else if (status[STATUS_UNDERFLOW]) {\r
-            n = status[STATUS_POSITIVE] ? new Double("0.0") : new Double("-0.0");\r
-        }\r
-\r
-        // Handle -0.0\r
-        else if (!status[STATUS_POSITIVE] && digitList.isZero()) {\r
-            n = new Double("-0.0");\r
-        }\r
-\r
-        else {\r
-            // Do as much of the multiplier conversion as possible without\r
-            // losing accuracy.\r
-            int mult = multiplier; // Don't modify this.multiplier\r
-            while (mult % 10 == 0) {\r
-                --digitList.decimalAt;\r
-                mult /= 10;\r
-            }\r
-\r
-            // Handle integral values\r
-            if (!parseBigDecimal && mult == 1 && digitList.isIntegral()) {\r
-                // hack quick long\r
-                if (digitList.decimalAt < 12) { // quick check for long\r
-                    long l = 0;\r
-                    if (digitList.count > 0) {\r
-                        int nx = 0;\r
-                        while (nx < digitList.count) {\r
-                            l = l * 10 + (char)digitList.digits[nx++] - '0';\r
-                        }\r
-                        while (nx++ < digitList.decimalAt) {\r
-                            l *= 10;\r
-                        }\r
-                        if (!status[STATUS_POSITIVE]) {\r
-                            l = -l;\r
-                        }\r
-                    }\r
-                    n = new Long(l);\r
-                } else {\r
-                    BigInteger big = digitList.getBigInteger(status[STATUS_POSITIVE]);\r
-                    n = (big.bitLength() < 64) ?\r
-                        (Number) new Long(big.longValue()) : (Number) big;\r
-                }\r
-            }\r
-            // Handle non-integral values or the case where parseBigDecimal is set\r
-            else {\r
-                BigDecimal big = digitList.getBigDecimalICU(status[STATUS_POSITIVE]);\r
-                n = big;\r
-                if (mult != 1) {\r
-                    n = big.divide(BigDecimal.valueOf(mult), mathContext);\r
-                }\r
-            }\r
-        }\r
-\r
-        // Assemble into CurrencyAmount if necessary\r
-        return parseCurrency ? (Object) new CurrencyAmount(n, currency[0])\r
-                             : (Object) n;\r
-    }\r
-\r
-\r
-    private boolean parseForCurrency(String text, ParsePosition parsePosition, \r
-                                     boolean parseCurrency, Currency[] currency,\r
-                                     boolean[] status) {\r
-        int origPos = parsePosition.getIndex();\r
-        if (!isReadyForParsing) {\r
-            int savedCurrencySignCount = currencySignCount;\r
-            setupCurrencyAffixForAllPatterns();\r
-            // reset pattern back\r
-            if (savedCurrencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT) {\r
-                applyPatternWithoutExpandAffix(formatPattern, false);\r
-            } else {\r
-                applyPattern(formatPattern, false);\r
-            }\r
-            isReadyForParsing = true;\r
-        }\r
-        int maxPosIndex = origPos;\r
-        int maxErrorPos = -1;\r
-        boolean[] savedStatus = null;\r
-        // First, parse against current pattern.\r
-        // Since current pattern could be set by applyPattern(),\r
-        // it could be an arbitrary pattern, and it may not be the one\r
-        // defined in current locale.\r
-        boolean[] tmpStatus = new boolean[STATUS_LENGTH];\r
-        ParsePosition tmpPos = new ParsePosition(origPos);\r
-        DigitList tmpDigitList = new DigitList();\r
-        boolean found;\r
-        if (style == NumberFormat.PLURALCURRENCYSTYLE) {\r
-            found  = subparse(text, tmpPos, tmpDigitList, false, \r
-                  tmpStatus, currency, negPrefixPattern, negSuffixPattern,\r
-                  posPrefixPattern, posSuffixPattern, Currency.LONG_NAME);\r
-        } else {\r
-            found  = subparse(text, tmpPos, tmpDigitList, false, \r
-                  tmpStatus, currency, negPrefixPattern, negSuffixPattern,\r
-                  posPrefixPattern, posSuffixPattern, Currency.SYMBOL_NAME);\r
-        }\r
-        if (found) {\r
-            if (tmpPos.getIndex() > maxPosIndex) {\r
-                maxPosIndex = tmpPos.getIndex();\r
-                savedStatus = tmpStatus;\r
-                digitList = tmpDigitList;\r
-            }\r
-        } else {\r
-            maxErrorPos = tmpPos.getErrorIndex();\r
-        }\r
-        // Then, parse against affix patterns.\r
-        // Those are currency patterns and currency plural patterns\r
-        // defined in the locale.\r
-        Iterator  iter = affixPatternsForCurrency.iterator();\r
-        while (iter.hasNext()) {\r
-            AffixForCurrency affix = (AffixForCurrency)iter.next();\r
-\r
-            tmpStatus = new boolean[STATUS_LENGTH];\r
-            tmpPos = new ParsePosition(origPos); \r
-            tmpDigitList = new DigitList();\r
-            boolean result = subparse(text, tmpPos, tmpDigitList, false, \r
-                               tmpStatus, currency, affix.getNegPrefix(),\r
-                               affix.getNegSuffix(), affix.getPosPrefix(), \r
-                               affix.getPosSuffix(), affix.getPatternType());\r
-            if (result) {\r
-                found = true;\r
-                if (tmpPos.getIndex() > maxPosIndex) {\r
-                    maxPosIndex = tmpPos.getIndex();\r
-                    savedStatus = tmpStatus;\r
-                    digitList = tmpDigitList;\r
-                }\r
-            } else {\r
-                maxErrorPos = (tmpPos.getErrorIndex() > maxErrorPos) ?\r
-                              tmpPos.getErrorIndex() : maxErrorPos;\r
-            }\r
-        }\r
-        // Finally, parse against simple affix to find the match.\r
-        // For example, in TestMonster suite,\r
-        // if the to-be-parsed text is "-\u00A40,00".\r
-        // complexAffixCompare will not find match,\r
-        // since there is no ISO code matches "\u00A4",\r
-        // and the parse stops at "\u00A4".\r
-        // We will just use simple affix comparison (look for exact match)\r
-        // to pass it.\r
-        tmpStatus = new boolean[STATUS_LENGTH];\r
-        tmpPos = new ParsePosition(origPos); \r
-        tmpDigitList = new DigitList();\r
-        int savedCurrencySignCount = currencySignCount;\r
-        // set currencySignCount to 0 so that compareAffix function will\r
-        // fall to compareSimpleAffix path, not compareComplexAffix path.\r
-        currencySignCount = 0;\r
-        boolean result = subparse(text, tmpPos, tmpDigitList, false, \r
-                  tmpStatus, currency, negativePrefix, negativeSuffix,\r
-                  positivePrefix, positiveSuffix, Currency.SYMBOL_NAME);\r
-        currencySignCount = savedCurrencySignCount;\r
-        if (result) {\r
-            if (tmpPos.getIndex() > maxPosIndex) {\r
-                maxPosIndex = tmpPos.getIndex();\r
-                savedStatus = tmpStatus;\r
-                digitList = tmpDigitList;\r
-            }\r
-            found = true;\r
-        } else {\r
-                maxErrorPos = (tmpPos.getErrorIndex() > maxErrorPos) ?\r
-                              tmpPos.getErrorIndex() : maxErrorPos;\r
-        }\r
-\r
-        if (!found) {\r
-            //parsePosition.setIndex(origPos);\r
-            parsePosition.setErrorIndex(maxErrorPos);\r
-        } else {\r
-            parsePosition.setIndex(maxPosIndex);\r
-            parsePosition.setErrorIndex(-1);\r
-            for (int index = 0; index < STATUS_LENGTH; ++index) {\r
-                status[index] = savedStatus[index];\r
-            }\r
-        }\r
-        return found;\r
-    }\r
-\r
-\r
-    // Get affix patterns used in locale's currency pattern\r
-    // (NumberPatterns[1]) and currency plural pattern (CurrencyUnitPatterns).\r
-    private void setupCurrencyAffixForAllPatterns() {\r
-        if (currencyPluralInfo == null) {\r
-            currencyPluralInfo = new CurrencyPluralInfo(symbols.getLocale());\r
-        }\r
-        affixPatternsForCurrency = new HashSet();\r
-\r
-        // save the current pattern, since it will be changed by\r
-        // applyPatternWithoutExpandAffix\r
-        String savedFormatPattern = formatPattern;\r
-        \r
-        // CURRENCYSTYLE and ISOCURRENCYSTYLE should have the same\r
-        // prefix and suffix, so, only need to save one of them.\r
-        // Here, chose onlyApplyPatternWithoutExpandAffix without\r
-        // saving the actualy pattern in 'pattern' data member.\r
-        // TODO: is it uloc?\r
-        applyPatternWithoutExpandAffix(getPattern(symbols.getLocale(), NumberFormat.CURRENCYSTYLE), false);\r
-        AffixForCurrency affixes = new AffixForCurrency(negPrefixPattern,\r
-                                                        negSuffixPattern,\r
-                                                        posPrefixPattern,\r
-                                                        posSuffixPattern,\r
-                                                        Currency.SYMBOL_NAME);\r
-        affixPatternsForCurrency.add(affixes);\r
-        \r
-        // add plural pattern\r
-        Iterator iter = currencyPluralInfo.pluralPatternIterator();\r
-        Set currencyUnitPatternSet = new HashSet();\r
-        while (iter.hasNext()) {\r
-            String pluralCount = (String)iter.next();\r
-            String currencyPattern = (String)currencyPluralInfo.getCurrencyPluralPattern(pluralCount);\r
-            if (currencyPattern != null &&\r
-                currencyUnitPatternSet.contains(currencyPattern) == false) {\r
-                currencyUnitPatternSet.add(currencyPattern);\r
-                applyPatternWithoutExpandAffix(currencyPattern, false);\r
-                affixes = new AffixForCurrency(negPrefixPattern,\r
-                                               negSuffixPattern,\r
-                                               posPrefixPattern,\r
-                                               posSuffixPattern,\r
-                                               Currency.LONG_NAME);\r
-                affixPatternsForCurrency.add(affixes);\r
-            }   \r
-        }\r
-        // reset pattern back\r
-        formatPattern = savedFormatPattern;\r
-    }\r
-\r
-    private static final int CURRENCY_SIGN_COUNT_IN_SYMBOL_FORMAT = 1;\r
-    private static final int CURRENCY_SIGN_COUNT_IN_ISO_FORMAT = 2;\r
-    private static final int CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT = 3;\r
-\r
-    private static final int STATUS_INFINITE = 0;\r
-    private static final int STATUS_POSITIVE = 1;\r
-    private static final int STATUS_UNDERFLOW = 2;\r
-    private static final int STATUS_LENGTH   = 3;\r
-    private static final UnicodeSet dotEquivalents =(UnicodeSet) new UnicodeSet(\r
-        "[.\u2024\u3002\uFE12\uFE52\uFF0E\uFF61]").freeze();\r
-    private static final UnicodeSet commaEquivalents = (UnicodeSet) new UnicodeSet(\r
-        "[,\u060C\u066B\u3001\uFE10\uFE11\uFE50\uFE51\uFF0C\uFF64]").freeze();\r
-    private static final UnicodeSet otherGroupingSeparators = (UnicodeSet) new UnicodeSet(\r
-        "[\\ '\u00A0\u066C\u2000-\u200A\u2018\u2019\u202F\u205F\u3000\uFF07]").freeze();\r
-    \r
-    private static final UnicodeSet strictDotEquivalents =(UnicodeSet) new UnicodeSet(\r
-        "[.\u2024\uFE52\uFF0E\uFF61]").freeze();\r
-    private static final UnicodeSet strictCommaEquivalents = (UnicodeSet) new UnicodeSet(\r
-        "[,\u066B\uFE10\uFE50\uFF0C]").freeze();\r
-    private static final UnicodeSet strictOtherGroupingSeparators = (UnicodeSet) new UnicodeSet(\r
-        "[\\ '\u00A0\u066C\u2000-\u200A\u2018\u2019\u202F\u205F\u3000\uFF07]").freeze();\r
-\r
-    private static final UnicodeSet defaultGroupingSeparators = (UnicodeSet) new UnicodeSet(\r
-        dotEquivalents).addAll(commaEquivalents).addAll(otherGroupingSeparators).freeze();\r
-    private static final UnicodeSet strictDefaultGroupingSeparators = (UnicodeSet) new UnicodeSet(\r
-            strictDotEquivalents).addAll(strictCommaEquivalents).addAll(strictOtherGroupingSeparators).freeze();\r
-\r
-    // When parsing a number with big exponential value, it requires to transform\r
-    // the value into a string representation to construct BigInteger instance.\r
-    // We want to set the maximum size because it can easily trigger OutOfMemoryException.\r
-    // PARSE_MAX_EXPONENT is currently set to 1000, which is much bigger than\r
-    // MAX_VALUE of Double (\r
-    // See the problem reported by ticket#5698\r
-    private static final int PARSE_MAX_EXPONENT = 1000;\r
-\r
-    /**\r
-     * <strong><font face=helvetica color=red>CHANGED</font></strong>\r
-     * Parse the given text into a number.  The text is parsed beginning at\r
-     * parsePosition, until an unparseable character is seen.\r
-     * @param text The string to parse.\r
-     * @param parsePosition The position at which to being parsing.  Upon\r
-     * return, the first unparseable character.\r
-     * @param digits The DigitList to set to the parsed value.\r
-     * @param isExponent If true, parse an exponent.  This means no\r
-     * infinite values and integer only.\r
-     * @param status Upon return contains boolean status flags indicating\r
-     * whether the value was infinite and whether it was positive.\r
-     * @param currency return value for parsed currency, for generic\r
-     * currency parsing mode, or null for normal parsing. In generic\r
-     * currency parsing mode, any currency is parsed, not just the\r
-     * currency that this formatter is set to.\r
-     * @param negPrefix negative prefix pattern\r
-     * @param negSuffix negative suffix pattern\r
-     * @param posPrefix positive prefix pattern\r
-     * @param negSuffix negative suffix pattern\r
-     * @param type type of currency to parse against, LONG_NAME only or not.\r
-     */\r
-    private final boolean subparse(String text, ParsePosition parsePosition,\r
-                   DigitList digits, boolean isExponent,\r
-                   boolean status[], Currency currency[],\r
-                   String negPrefix, String negSuffix,\r
-                   String posPrefix, String posSuffix,\r
-                   int type)\r
-    {\r
-        int position = parsePosition.getIndex();\r
-        int oldStart = parsePosition.getIndex();\r
-\r
-        // Match padding before prefix\r
-        if (formatWidth > 0 && padPosition == PAD_BEFORE_PREFIX) {\r
-            position = skipPadding(text, position);\r
-        }\r
-\r
-        // Match positive and negative prefixes; prefer longest match.\r
-        int posMatch = compareAffix(text, position, false, true, posPrefix, type, currency);\r
-        int negMatch = compareAffix(text, position, true, true, negPrefix, type, currency);\r
-        if (posMatch >= 0 && negMatch >= 0) {\r
-            if (posMatch > negMatch) {\r
-                negMatch = -1;\r
-            } else if (negMatch > posMatch) {\r
-                posMatch = -1;\r
-            }  \r
-        }\r
-        if (posMatch >= 0) {\r
-            position += posMatch;\r
-        } else if (negMatch >= 0) {\r
-            position += negMatch;\r
-        } else {\r
-            parsePosition.setErrorIndex(position);\r
-            return false;\r
-        }\r
-\r
-        // Match padding after prefix\r
-        if (formatWidth > 0 && padPosition == PAD_AFTER_PREFIX) {\r
-            position = skipPadding(text, position);\r
-        }\r
-\r
-        // process digits or Inf, find decimal position\r
-        status[STATUS_INFINITE] = false;\r
-        if (!isExponent && text.regionMatches(position,symbols.getInfinity(),0,\r
-                          symbols.getInfinity().length()))\r
-        {\r
-            position += symbols.getInfinity().length();\r
-            status[STATUS_INFINITE] = true;\r
-        } else {\r
-            // We now have a string of digits, possibly with grouping symbols,\r
-            // and decimal points.  We want to process these into a DigitList.\r
-            // We don't want to put a bunch of leading zeros into the DigitList\r
-            // though, so we keep track of the location of the decimal point,\r
-            // put only significant digits into the DigitList, and adjust the\r
-            // exponent as needed.\r
-\r
-            digits.decimalAt = digits.count = 0;\r
-            char zero = symbols.getZeroDigit();\r
-            char decimal = currencySignCount > 0 ?\r
-            symbols.getMonetaryDecimalSeparator() : symbols.getDecimalSeparator();\r
-            char grouping = symbols.getGroupingSeparator();\r
-                        \r
-            String exponentSep = symbols.getExponentSeparator();\r
-            boolean sawDecimal = false;\r
-            boolean sawExponent = false;\r
-            boolean sawDigit = false;\r
-            long exponent = 0; // Set to the exponent value, if any\r
-            int digit = 0;\r
-\r
-            // strict parsing\r
-            boolean strictParse = isParseStrict();\r
-            boolean strictFail = false; // did we exit with a strict parse failure?\r
-            int lastGroup = -1; // where did we last see a grouping separator?\r
-            int gs2 = groupingSize2 == 0 ? groupingSize : groupingSize2;\r
-\r
-            // Strict parsing leading zeroes.  If a leading zero would\r
-            // be forced by the pattern, then don't fail strict parsing.\r
-            boolean strictLeadingZero = false;\r
-            int leadingZeroPos   = 0;\r
-            int leadingZeroCount = 0;\r
-            \r
-            // equivalent grouping and decimal support\r
-            \r
-            // TODO markdavis Cache these if it makes a difference in performance.\r
-            UnicodeSet decimalSet = new UnicodeSet(getSimilarDecimals(decimal, strictParse));\r
-            UnicodeSet groupingSet = new UnicodeSet(strictParse ? strictDefaultGroupingSeparators : defaultGroupingSeparators)\r
-                .add(grouping).removeAll(decimalSet);\r
-            \r
-            // we are guaranteed that \r
-            // decimalSet contains the decimal, and \r
-            // groupingSet contains the groupingSeparator\r
-            // (unless decimal and grouping are the same, which should never happen. But in that case, groupingSet will just be empty.)\r
-\r
-\r
-            // We have to track digitCount ourselves, because digits.count will\r
-            // pin when the maximum allowable digits is reached.\r
-            int digitCount = 0;\r
-            \r
-            int backup = -1;\r
-            for (; position < text.length(); ++position)\r
-            {\r
-                char ch = text.charAt(position);\r
-\r
-                /* We recognize all digit ranges, not only the Latin digit range\r
-                 * '0'..'9'.  We do so by using the UCharacter.digit() method,\r
-                 * which converts a valid Unicode digit to the range 0..9.\r
-                 *\r
-                 * The character 'ch' may be a digit.  If so, place its value\r
-                 * from 0 to 9 in 'digit'.  First try using the locale digit,\r
-                 * which may or MAY NOT be a standard Unicode digit range.  If\r
-                 * this fails, try using the standard Unicode digit ranges by\r
-                 * calling UCharacter.digit().  If this also fails, digit will\r
-                 * have a value outside the range 0..9.\r
-                 */\r
-                digit = ch - zero;\r
-                if (digit < 0 || digit > 9) digit = UCharacter.digit(ch, 10);\r
-\r
-                if (digit == 0)\r
-                {\r
-                    // Cancel out backup setting (see grouping handler below)\r
-                    if (strictParse && backup != -1) {\r
-                        // comma followed by digit, so group before comma is a \r
-                        // secondary group.  If there was a group separator\r
-                        // before that, the group must == the secondary group\r
-                        // length, else it can be <= the the secondary group\r
-                        // length.\r
-                        if ((lastGroup != -1 && backup - lastGroup - 1 != gs2) ||\r
-                            (lastGroup == -1 && position - oldStart - 1 > gs2)) {\r
-                            strictFail = true;\r
-                            break;\r
-                        }\r
-                        lastGroup = backup;\r
-                    }\r
-                    backup = -1; // Do this BEFORE continue statement below!!!\r
-                    sawDigit = true;\r
-\r
-                    // Handle leading zeros\r
-                    if (digits.count == 0)\r
-                    {\r
-                        if (!sawDecimal) {\r
-                            if (strictParse && !isExponent) {\r
-                                // Allow leading zeros in exponents\r
-                                // Count leading zeros for checking later\r
-                                if (!strictLeadingZero) leadingZeroPos = position + 1;\r
-                                strictLeadingZero = true;\r
-                                ++leadingZeroCount;                                \r
-                            }\r
-                            // Ignore leading zeros in integer part of number.\r
-                            continue;\r
-                        }\r
-\r
-                        // If we have seen the decimal, but no significant digits yet,\r
-                        // then we account for leading zeros by decrementing the\r
-                        // digits.decimalAt into negative values.\r
-                        --digits.decimalAt;\r
-                    }\r
-                    else\r
-                    {\r
-                        ++digitCount;\r
-                        digits.append((char)(digit + '0'));\r
-                    }\r
-                }\r
-                else if (digit > 0 && digit <= 9) // [sic] digit==0 handled above\r
-                {\r
-                    if (strictParse) {\r
-                        if (backup != -1) {\r
-                            if ((lastGroup != -1 && backup - lastGroup - 1 != gs2) ||\r
-                                (lastGroup == -1 && position - oldStart - 1 > gs2)) {\r
-                                strictFail = true;\r
-                                break;\r
-                            }\r
-                            lastGroup = backup;\r
-                        }\r
-                    }\r
-\r
-                    sawDigit = true;\r
-                    ++digitCount;\r
-                    digits.append((char)(digit + '0'));\r
-\r
-                    // Cancel out backup setting (see grouping handler below)\r
-                    backup = -1;\r
-                }\r
-                else if (!isExponent && decimalSet.contains(ch))\r
-                {\r
-                    if (strictParse) {\r
-                        if (backup != -1 ||\r
-                            (lastGroup != -1 && position - lastGroup != groupingSize + 1)) {\r
-                            strictFail = true;\r
-                            break;\r
-                        }\r
-                    }\r
-                    // If we're only parsing integers, or if we ALREADY saw the\r
-                    // decimal, then don't parse this one.\r
-                    if (isParseIntegerOnly() || sawDecimal) break;\r
-                    digits.decimalAt = digitCount; // Not digits.count!\r
-                    sawDecimal = true;\r
-                    \r
-                    // Once we see a decimal character, we only accept that decimal character from then on.\r
-                    decimalSet.set(ch,ch);\r
-                }\r
-                else if (!isExponent && isGroupingUsed() && groupingSet.contains(ch))\r
-                {\r
-                    if (sawDecimal) {\r
-                        break;\r
-                    }\r
-                    if (strictParse) {\r
-                        if ((!sawDigit || backup != -1)) {\r
-                            // leading group, or two group separators in a row\r
-                            strictFail = true;\r
-                            break;\r
-                        }\r
-                    }\r
-                    // Once we see a grouping character, we only accept that grouping character from then on.\r
-                    groupingSet.set(ch,ch);\r
-                    \r
-                    // Ignore grouping characters, if we are using them, but require\r
-                    // that they be followed by a digit.  Otherwise we backup and\r
-                    // reprocess them.\r
-                    backup = position;\r
-                }\r
-                else if (!isExponent && !sawExponent &&\r
-                         text.regionMatches(position, exponentSep,\r
-                                            0, exponentSep.length()))\r
-                {\r
-                    // Parse sign, if present\r
-                    boolean negExp = false;\r
-                    int pos = position + exponentSep.length();\r
-                    if (pos < text.length()) {\r
-                        ch = text.charAt(pos);\r
-                        if (ch == symbols.getPlusSign()) {\r
-                            ++pos;\r
-                        } else if (ch == symbols.getMinusSign()) {\r
-                            ++pos;\r
-                            negExp = true;\r
-                        }\r
-                    }\r
-\r
-                    DigitList exponentDigits = new DigitList();\r
-                    exponentDigits.count = 0;\r
-                    while (pos < text.length()) {\r
-                        digit = text.charAt(pos) - zero;\r
-                        if (digit < 0 || digit > 9) {\r
-                            /*\r
-                              Can't parse "[1E0]" when pattern is "0.###E0;[0.###E0]"\r
-                              Should update reassign the value of 'ch' in the\r
-                              code:  digit = Character.digit(ch, 10);\r
-                              [Richard/GCL]\r
-                            */\r
-                            digit = UCharacter.digit(text.charAt(pos), 10);\r
-                        }\r
-                        if (digit >= 0 && digit <= 9) {\r
-                            exponentDigits.append((char)(digit + '0'));\r
-                            ++pos;\r
-                        } else {\r
-                            break;\r
-                        }\r
-                    }\r
-                    \r
-                    if (exponentDigits.count > 0) {\r
-                        // defer strict parse until we know we have a bona-fide exponent\r
-                        if (strictParse) {\r
-                            if (backup != -1 || lastGroup != -1) {\r
-                                strictFail = true;\r
-                                break;\r
-                            }\r
-                        }\r
-\r
-                        // Quick overflow check for exponential part.\r
-                        // Actual limit check will be done later in this code.\r
-                        if (exponentDigits.count > 10 /* maximum decimal digits for int */) {\r
-                            if (negExp) {\r
-                                // set underflow flag\r
-                                status[STATUS_UNDERFLOW] = true;\r
-                            } else {\r
-                                // set infinite flag\r
-                                status[STATUS_INFINITE] = true;\r
-                            }\r
-                        } else {\r
-                            exponentDigits.decimalAt = exponentDigits.count;\r
-                            exponent = exponentDigits.getLong();\r
-                            if (negExp) {\r
-                                exponent = -exponent;\r
-                            }\r
-                        }\r
-                        position = pos; // Advance past the exponent\r
-                        sawExponent = true;\r
-                    }\r
-\r
-                    break; // Whether we fail or succeed, we exit this loop\r
-                }\r
-                else break;\r
-            }\r
-\r
-            if (backup != -1) position = backup;\r
-\r
-            // If there was no decimal point we have an integer\r
-            if (!sawDecimal) digits.decimalAt = digitCount; // Not digits.count!            \r
-            \r
-            // check for strict parse errors\r
-            if (strictParse && strictLeadingZero) {\r
-                if ((leadingZeroCount + digits.decimalAt) > this.getMinimumIntegerDigits()) {\r
-                    parsePosition.setIndex(oldStart);\r
-                    parsePosition.setErrorIndex(leadingZeroPos);\r
-                    return false;\r
-                }\r
-            }\r
-            if (strictParse && !sawDecimal) {\r
-                if (lastGroup != -1 && position - lastGroup != groupingSize + 1) {\r
-                    strictFail = true;\r
-                }\r
-            }\r
-            if (strictFail) {\r
-                // only set with strictParse and a leading zero error\r
-                // leading zeros are an error with strict parsing except\r
-                // immediately before nondigit (except group separator \r
-                // followed by digit), or end of text.\r
-                \r
-                parsePosition.setIndex(oldStart);\r
-                parsePosition.setErrorIndex(position);\r
-                return false;\r
-            }\r
-\r
-            // Adjust for exponent, if any\r
-            exponent += digits.decimalAt;\r
-            if (exponent < -PARSE_MAX_EXPONENT) {\r
-                status[STATUS_UNDERFLOW] = true;\r
-            } else if (exponent > PARSE_MAX_EXPONENT) {\r
-                status[STATUS_INFINITE] = true;\r
-            } else {\r
-                digits.decimalAt = (int)exponent;\r
-            }\r
-\r
-            // If none of the text string was recognized.  For example, parse\r
-            // "x" with pattern "#0.00" (return index and error index both 0)\r
-            // parse "$" with pattern "$#0.00". (return index 0 and error index\r
-            // 1).\r
-            if (!sawDigit && digitCount == 0) {\r
-                parsePosition.setIndex(oldStart);\r
-                parsePosition.setErrorIndex(oldStart);\r
-                return false;\r
-            }\r
-        }\r
-\r
-        // Match padding before suffix\r
-        if (formatWidth > 0 && padPosition == PAD_BEFORE_SUFFIX) {\r
-            position = skipPadding(text, position);\r
-        }\r
-\r
-        // Match positive and negative suffixes; prefer longest match.\r
-        if (posMatch >= 0) {\r
-            posMatch = compareAffix(text, position, false, false, posSuffix, type, currency);\r
-        }\r
-        if (negMatch >= 0) {\r
-            negMatch = compareAffix(text, position, true, false, negSuffix, type, currency);\r
-        }\r
-        if (posMatch >= 0 && negMatch >= 0) {\r
-            if (posMatch > negMatch) {\r
-                negMatch = -1;\r
-            } else if (negMatch > posMatch) {\r
-                posMatch = -1;\r
-            }  \r
-        }\r
-\r
-        // Fail if neither or both\r
-        if ((posMatch >= 0) == (negMatch >= 0)) {\r
-            parsePosition.setErrorIndex(position);\r
-            return false;\r
-        }\r
-\r
-        position += (posMatch>=0 ? posMatch : negMatch);\r
-\r
-        // Match padding after suffix\r
-        if (formatWidth > 0 && padPosition == PAD_AFTER_SUFFIX) {\r
-            position = skipPadding(text, position);\r
-        }\r
-\r
-        parsePosition.setIndex(position);\r
-\r
-        status[STATUS_POSITIVE] = (posMatch >= 0);\r
-\r
-        if (parsePosition.getIndex() == oldStart) {\r
-            parsePosition.setErrorIndex(position);\r
-            return false;\r
-        }\r
-        return true;\r
-    }\r
-\r
-    /**\r
-     * Return characters that are used where this decimal is used.\r
-     * @param decimal\r
-     * @param strictParse \r
-     * @return\r
-     */\r
-    private UnicodeSet getSimilarDecimals(char decimal, boolean strictParse) {\r
-        if (dotEquivalents.contains(decimal)) {\r
-            return strictParse ? strictDotEquivalents : dotEquivalents;\r
-        }\r
-        if (commaEquivalents.contains(decimal)) {\r
-            return strictParse ? strictCommaEquivalents : commaEquivalents;\r
-        }\r
-        // if there is no match, return the character itself\r
-        return new UnicodeSet().add(decimal);\r
-    }\r
-\r
-    /**\r
-     * Starting at position, advance past a run of pad characters, if any.\r
-     * Return the index of the first character after position that is not a pad\r
-     * character.  Result is >= position.\r
-     */\r
-    private final int skipPadding(String text, int position) {\r
-        while (position < text.length() && text.charAt(position) == pad) {\r
-            ++position;\r
-        }\r
-        return position;\r
-    }\r
-\r
-    /*\r
-     * Return the length matched by the given affix, or -1 if none.\r
-     * Runs of white space in the affix, match runs of white space in\r
-     * the input.  Pattern white space and input white space are\r
-     * determined differently; see code.\r
-     * @param text input text\r
-     * @param pos offset into input at which to begin matching\r
-     * @param isNegative\r
-     * @param isPrefix\r
-     * @param affixPat affix pattern used for currency affix comparison\r
-     * @param type compare against currency type, LONG_NAME only or not.\r
-     * @param currency return value for parsed currency, for generic\r
-     * currency parsing mode, or null for normal parsing. In generic\r
-     * currency parsing mode, any currency is parsed, not just the\r
-     * currency that this formatter is set to.\r
-     * @return length of input that matches, or -1 if match failure\r
-     */\r
-    private int compareAffix(String text, int pos, \r
-                             boolean isNegative, boolean isPrefix,\r
-                             String affixPat,\r
-                             int type,\r
-                             Currency[] currency) {\r
-        if (currency != null || currencyChoice != null ||\r
-            currencySignCount > 0) {\r
-                return compareComplexAffix(affixPat, text, pos, type, currency);\r
-        }\r
-        if (isPrefix) {\r
-            return compareSimpleAffix(isNegative ? negativePrefix : positivePrefix,\r
-                                      text, pos);\r
-        } else {\r
-            return compareSimpleAffix(isNegative ? negativeSuffix : positiveSuffix,\r
-                                      text, pos);\r
-        }\r
-\r
-    }\r
-\r
-\r
-\r
-    /**\r
-     * Return the length matched by the given affix, or -1 if none.\r
-     * Runs of white space in the affix, match runs of white space in\r
-     * the input.  Pattern white space and input white space are\r
-     * determined differently; see code.\r
-     * @param affix pattern string, taken as a literal\r
-     * @param input input text\r
-     * @param pos offset into input at which to begin matching\r
-     * @return length of input that matches, or -1 if match failure\r
-     */\r
-    private static int compareSimpleAffix(String affix, String input, int pos) {\r
-        int start = pos;\r
-        for (int i=0; i<affix.length(); ) {\r
-            int c = UTF16.charAt(affix, i);\r
-            int len = UTF16.getCharCount(c);\r
-            if (UCharacterProperty.isRuleWhiteSpace(c)) {\r
-                // We may have a pattern like: \u200F \u0020\r
-                //        and input text like: \u200F \u0020\r
-                // Note that U+200F and U+0020 are RuleWhiteSpace but only\r
-                // U+0020 is UWhiteSpace.  So we have to first do a direct\r
-                // match of the run of RULE whitespace in the pattern,\r
-                // then match any extra characters.\r
-                boolean literalMatch = false;\r
-                while (pos < input.length() &&\r
-                       UTF16.charAt(input, pos) == c) {\r
-                    literalMatch = true;\r
-                    i += len;\r
-                    pos += len;\r
-                    if (i == affix.length()) {\r
-                        break;\r
-                    }\r
-                    c = UTF16.charAt(affix, i);\r
-                    len = UTF16.getCharCount(c);\r
-                    if (!UCharacterProperty.isRuleWhiteSpace(c)) {\r
-                        break;\r
-                    }\r
-                }\r
-                \r
-                // Advance over run in affix\r
-                i = skipRuleWhiteSpace(affix, i);\r
-                \r
-                // Advance over run in input text\r
-                // Must see at least one white space char in input,\r
-                // unless we've already matched some characters literally.\r
-                int s = pos;\r
-                pos = skipUWhiteSpace(input, pos);\r
-                if (pos == s && !literalMatch) {\r
-                    return -1;\r
-                }\r
-                // If we skip UWhiteSpace in the input text, we need to skip it in the pattern.\r
-                // Otherwise, the previous lines may have skipped over text (such as U+00A0) that\r
-                // is also in the affix.\r
-                i = skipUWhiteSpace(affix, i);\r
-            } else {\r
-                if (pos < input.length() &&\r
-                    UTF16.charAt(input, pos) == c) {\r
-                    i += len;\r
-                    pos += len;\r
-                } else {\r
-                    return -1;\r
-                }\r
-            }\r
-        }\r
-        return pos - start;\r
-    }\r
-\r
-    /**\r
-     * Skip over a run of zero or more isRuleWhiteSpace() characters at\r
-     * pos in text.\r
-     */\r
-    private static int skipRuleWhiteSpace(String text, int pos) {\r
-        while (pos < text.length()) {\r
-            int c = UTF16.charAt(text, pos);\r
-            if (!UCharacterProperty.isRuleWhiteSpace(c)) {\r
-                break;\r
-            }\r
-            pos += UTF16.getCharCount(c);\r
-        }\r
-        return pos;\r
-    }\r
-\r
-    /**\r
-     * Skip over a run of zero or more isUWhiteSpace() characters at pos\r
-     * in text.\r
-     */\r
-    private static int skipUWhiteSpace(String text, int pos) {\r
-        while (pos < text.length()) {\r
-            int c = UTF16.charAt(text, pos);\r
-            if (!UCharacter.isUWhiteSpace(c)) {\r
-                break;\r
-            }\r
-            pos += UTF16.getCharCount(c);\r
-        }\r
-        return pos;\r
-    }\r
-\r
-    /*\r
-     * Return the length matched by the given affix, or -1 if none.\r
-     * @param affixPat pattern string\r
-     * @param text input text\r
-     * @param pos offset into input at which to begin matching\r
-     * @param type parse against currency type, LONG_NAME only or not.\r
-     * @param currency return value for parsed currency, for generic\r
-     * currency parsing mode, or null for normal parsing. In generic\r
-     * currency parsing mode, any currency is parsed, not just the\r
-     * currency that this formatter is set to.\r
-     * @return position after the matched text, or -1 if match failure\r
-     */\r
-    private int compareComplexAffix(String affixPat, String text, int pos,\r
-                                    int type, Currency[] currency) {\r
-        int start = pos;\r
-        for (int i=0; \r
-             i < affixPat.length() && pos >= 0; ) {\r
-            char c = affixPat.charAt(i++);\r
-            if (c == QUOTE) {\r
-                for (;;) {\r
-                    int j = affixPat.indexOf(QUOTE, i);\r
-                    if (j == i) {\r
-                        pos = match(text, pos, QUOTE);\r
-                        i = j+1;\r
-                        break;\r
-                    } else if (j > i) {\r
-                        pos = match(text, pos, affixPat.substring(i, j));\r
-                        i = j+1;\r
-                        if (i<affixPat.length() &&\r
-                            affixPat.charAt(i)==QUOTE) {\r
-                            pos = match(text, pos, QUOTE);\r
-                            ++i;\r
-                            // loop again\r
-                        } else {\r
-                            break;\r
-                        }\r
-                    } else {\r
-                        // Unterminated quote; should be caught by apply\r
-                        // pattern.\r
-                        throw new RuntimeException();\r
-                    }\r
-                }\r
-                continue;\r
-            }\r
-\r
-            switch (c) {\r
-            case CURRENCY_SIGN:\r
-                // since the currency names in choice format is saved\r
-                // the same way as other currency names, \r
-                // do not need to do currency choice parsing here.\r
-                // the general currency parsing parse against all names,\r
-                // including names in choice format.\r
-                //assert(currency != null ||\r
-                //       (getCurrency() != null && currencyChoice != null));\r
-                boolean intl = i<affixPat.length() &&\r
-                    affixPat.charAt(i) == CURRENCY_SIGN;\r
-                if (intl) {\r
-                    ++i;\r
-                }\r
-                boolean plural = i<affixPat.length() &&\r
-                    affixPat.charAt(i) == CURRENCY_SIGN;\r
-                if (plural) {\r
-                    ++i;\r
-                    intl = false;\r
-                }\r
-                // Parse generic currency -- anything for which we\r
-                // have a display name, or any 3-letter ISO code.\r
-                // Try to parse display name for our locale; first\r
-                // determine our locale.\r
-                // TODO: use locale in CurrencyPluralInfo\r
-                ULocale uloc = getLocale(ULocale.VALID_LOCALE);\r
-                if (uloc == null) {\r
-                    // applyPattern has been called; use the symbols\r
-                    uloc = symbols.getLocale(ULocale.VALID_LOCALE);\r
-                }\r
-                // Delegate parse of display name => ISO code to Currency\r
-                ParsePosition ppos = new ParsePosition(pos);\r
-                // using Currency.parse to handle mixed style parsing.\r
-                String iso = Currency.parse(uloc, text, type, ppos);\r
-\r
-                // If parse succeeds, populate currency[0]\r
-                if (iso != null) {\r
-                    if (currency != null) {\r
-                        currency[0] = Currency.getInstance(iso);\r
-                    }\r
-                    pos = ppos.getIndex();\r
-                } else {\r
-                    pos = -1;\r
-                }\r
-                continue;\r
-            case PATTERN_PERCENT:\r
-                c = symbols.getPercent();\r
-                break;\r
-            case PATTERN_PER_MILLE:\r
-                c = symbols.getPerMill();\r
-                break;\r
-            case PATTERN_MINUS:\r
-                c = symbols.getMinusSign();\r
-                break;\r
-            }\r
-            pos = match(text, pos, c);\r
-            if (UCharacterProperty.isRuleWhiteSpace(c)) {\r
-                i = skipRuleWhiteSpace(affixPat, i);\r
-            }\r
-        }\r
-\r
-        return pos - start;\r
-    }\r
-\r
-    /**\r
-     * Match a single character at text[pos] and return the index of the\r
-     * next character upon success.  Return -1 on failure.  If\r
-     * isRuleWhiteSpace(ch) then match a run of white space in text.\r
-     */\r
-    static final int match(String text, int pos, int ch) {\r
-        if (pos >= text.length()) { \r
-            return -1; \r
-        } \r
-        if (UCharacterProperty.isRuleWhiteSpace(ch)) {\r
-            // Advance over run of white space in input text\r
-            // Must see at least one white space char in input\r
-            int s = pos;\r
-            pos = skipUWhiteSpace(text, pos);\r
-            if (pos == s) {\r
-                return -1;\r
-            }\r
-            return pos;\r
-        }\r
-        return (pos >= 0 && UTF16.charAt(text, pos) == ch) ?\r
-            (pos + UTF16.getCharCount(ch)) : -1;\r
-    }\r
-\r
-    /**\r
-     * Match a string at text[pos] and return the index of the next\r
-     * character upon success.  Return -1 on failure.  Match a run of\r
-     * white space in str with a run of white space in text.\r
-     */\r
-    static final int match(String text, int pos, String str) {\r
-        for (int i=0; i<str.length() && pos >= 0; ) {\r
-            int ch = UTF16.charAt(str, i);\r
-            i += UTF16.getCharCount(ch);\r
-            pos = match(text, pos, ch);\r
-            if (UCharacterProperty.isRuleWhiteSpace(ch)) {\r
-                i = skipRuleWhiteSpace(str, i);\r
-            }\r
-        }\r
-        return pos;\r
-    }\r
-\r
-    /**\r
-     * Returns a copy of the decimal format symbols used by this format.\r
-     * @return desired DecimalFormatSymbols\r
-     * @see DecimalFormatSymbols\r
-     * @stable ICU 2.0\r
-     */\r
-    public DecimalFormatSymbols getDecimalFormatSymbols() {\r
-        try {\r
-            // don't allow multiple references\r
-            return (DecimalFormatSymbols) symbols.clone();\r
-        } catch (Exception foo) {\r
-            return null; // should never happen\r
-        }\r
-    }\r
-\r
-\r
-    /**\r
-     * Sets the decimal format symbols used by this format.  The\r
-     * format uses a copy of the provided symbols.\r
-     * @param newSymbols desired DecimalFormatSymbols\r
-     * @see DecimalFormatSymbols\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) {\r
-        symbols = (DecimalFormatSymbols) newSymbols.clone();\r
-        setCurrencyForSymbols();\r
-        expandAffixes(null);\r
-    }\r
-\r
-    /**\r
-     * Update the currency object to match the symbols.  This method\r
-     * is used only when the caller has passed in a symbols object\r
-     * that may not be the default object for its locale.\r
-     */\r
-    private void setCurrencyForSymbols() {\r
-        /*Bug 4212072\r
-          Update the affix strings according to symbols in order to keep\r
-          the affix strings up to date.\r
-          [Richard/GCL]\r
-        */\r
-        \r
-        // With the introduction of the Currency object, the currency\r
-        // symbols in the DFS object are ignored.  For backward\r
-        // compatibility, we check any explicitly set DFS object.  If it\r
-        // is a default symbols object for its locale, we change the\r
-        // currency object to one for that locale.  If it is custom,\r
-        // we set the currency to null.\r
-        DecimalFormatSymbols def =\r
-            new DecimalFormatSymbols(symbols.getLocale());\r
-        \r
-        if (symbols.getCurrencySymbol().equals(\r
-                def.getCurrencySymbol()) &&\r
-            symbols.getInternationalCurrencySymbol().equals(\r
-                def.getInternationalCurrencySymbol())) {\r
-            setCurrency(Currency.getInstance(symbols.getLocale()));\r
-        } else {\r
-            setCurrency(null);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Get the positive prefix.\r
-     * <P>Examples: +123, $123, sFr123\r
-     * @stable ICU 2.0\r
-     */\r
-    public String getPositivePrefix () {\r
-        return positivePrefix;\r
-    }\r
-\r
-    /**\r
-     * Set the positive prefix.\r
-     * <P>Examples: +123, $123, sFr123\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setPositivePrefix (String newValue) {\r
-        positivePrefix = newValue;\r
-        posPrefixPattern = null;\r
-    }\r
-\r
-    /**\r
-     * Get the negative prefix.\r
-     * <P>Examples: -123, ($123) (with negative suffix), sFr-123\r
-     * @stable ICU 2.0\r
-     */\r
-    public String getNegativePrefix () {\r
-        return negativePrefix;\r
-    }\r
-\r
-    /**\r
-     * Set the negative prefix.\r
-     * <P>Examples: -123, ($123) (with negative suffix), sFr-123\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setNegativePrefix (String newValue) {\r
-        negativePrefix = newValue;\r
-        negPrefixPattern = null;\r
-    }\r
-\r
-    /**\r
-     * Get the positive suffix.\r
-     * <P>Example: 123%\r
-     * @stable ICU 2.0\r
-     */\r
-    public String getPositiveSuffix () {\r
-        return positiveSuffix;\r
-    }\r
-\r
-    /**\r
-     * Set the positive suffix.\r
-     * <P>Example: 123%\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setPositiveSuffix (String newValue) {\r
-        positiveSuffix = newValue;\r
-        posSuffixPattern = null;\r
-    }\r
-\r
-    /**\r
-     * Get the negative suffix.\r
-     * <P>Examples: -123%, ($123) (with positive suffixes)\r
-     * @stable ICU 2.0\r
-     */\r
-    public String getNegativeSuffix () {\r
-        return negativeSuffix;\r
-    }\r
-\r
-    /**\r
-     * Set the positive suffix.\r
-     * <P>Examples: 123%\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setNegativeSuffix (String newValue) {\r
-        negativeSuffix = newValue;\r
-        negSuffixPattern = null;\r
-    }\r
-\r
-    /**\r
-     * Get the multiplier for use in percent, permill, etc.\r
-     * For a percentage, set the suffixes to have "%" and the multiplier to be 100.\r
-     * (For Arabic, use arabic percent symbol).\r
-     * For a permill, set the suffixes to have "\u2031" and the multiplier to be 1000.\r
-     * <P>Examples: with 100, 1.23 -> "123", and "123" -> 1.23\r
-     * @stable ICU 2.0\r
-     */\r
-    public int getMultiplier () {\r
-        return multiplier;\r
-    }\r
-\r
-    /**\r
-     * Set the multiplier for use in percent, permill, etc.\r
-     * For a percentage, set the suffixes to have "%" and the multiplier to be 100.\r
-     * (For Arabic, use arabic percent symbol).\r
-     * For a permill, set the suffixes to have "\u2031" and the multiplier to be 1000.\r
-     * <P>Examples: with 100, 1.23 -> "123", and "123" -> 1.23\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setMultiplier (int newValue) {\r
-        if (newValue == 0) {\r
-            throw new IllegalArgumentException("Bad multiplier: " + newValue);\r
-        }\r
-        multiplier = newValue;\r
-    }\r
-    \r
-    // [NEW]\r
-    /**\r
-     * Get the rounding increment.\r
-     * @return A positive rounding increment, or <code>null</code> if rounding\r
-     * is not in effect.\r
-     * @see #setRoundingIncrement\r
-     * @see #getRoundingMode\r
-     * @see #setRoundingMode\r
-     * @stable ICU 2.0\r
-     */\r
-//#if defined(FOUNDATION10) || defined(ECLIPSE_FRAGMENT)\r
-//##    public BigDecimal getRoundingIncrement() {\r
-//##        if (roundingIncrementICU == null) return null;\r
-//##        return new BigDecimal(roundingIncrementICU.toString());\r
-//##    }\r
-//#else\r
-    public java.math.BigDecimal getRoundingIncrement() {\r
-        if (roundingIncrementICU == null) return null;\r
-        return roundingIncrementICU.toBigDecimal();\r
-    }\r
-//#endif\r
-    \r
-//#if defined(FOUNDATION10)\r
-//#else\r
-    // [NEW]\r
-    /**\r
-     * Set the rounding increment.  This method also controls whether\r
-     * rounding is enabled.\r
-     * @param newValue A positive rounding increment, or <code>null</code> or\r
-     * <code>BigDecimal(0.0)</code> to disable rounding.\r
-     * @exception IllegalArgumentException if <code>newValue</code> is < 0.0\r
-     * @see #getRoundingIncrement\r
-     * @see #getRoundingMode\r
-     * @see #setRoundingMode\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setRoundingIncrement(java.math.BigDecimal newValue) {\r
-        if (newValue == null) {\r
-            setRoundingIncrement((BigDecimal)null);\r
-        } else {\r
-            setRoundingIncrement(new BigDecimal(newValue));\r
-        }\r
-    }\r
-//#endif\r
-    \r
-    // [NEW]\r
-    /**\r
-     * Set the rounding increment.  This method also controls whether\r
-     * rounding is enabled.\r
-     * @param newValue A positive rounding increment, or <code>null</code> or\r
-     * <code>BigDecimal(0.0)</code> to disable rounding.\r
-     * @exception IllegalArgumentException if <code>newValue</code> is < 0.0\r
-     * @see #getRoundingIncrement\r
-     * @see #getRoundingMode\r
-     * @see #setRoundingMode\r
-     * @stable ICU 3.6\r
-     */\r
-    public void setRoundingIncrement(BigDecimal newValue) {\r
-        int i = newValue == null\r
-            ? 0 : newValue.compareTo(BigDecimal.ZERO);\r
-        if (i < 0) {\r
-            throw new IllegalArgumentException("Illegal rounding increment");\r
-        }\r
-        if (i == 0) {\r
-            setInternalRoundingIncrement(null);\r
-        } else {\r
-            setInternalRoundingIncrement(newValue);\r
-        }\r
-        setRoundingDouble();\r
-    }\r
-\r
-    // [NEW]\r
-    /**\r
-     * Set the rounding increment.  This method also controls whether\r
-     * rounding is enabled.\r
-     * @param newValue A positive rounding increment, or 0.0 to disable\r
-     * rounding.\r
-     * @exception IllegalArgumentException if <code>newValue</code> is < 0.0\r
-     * @see #getRoundingIncrement\r
-     * @see #getRoundingMode\r
-     * @see #setRoundingMode\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setRoundingIncrement(double newValue) {\r
-        if (newValue < 0.0) {\r
-            throw new IllegalArgumentException("Illegal rounding increment");\r
-        }\r
-        roundingDouble = newValue;\r
-        roundingDoubleReciprocal = 0.0d;\r
-        if (newValue == 0.0d) {\r
-            setRoundingIncrement((BigDecimal)null);\r
-        } else {\r
-            roundingDouble = newValue;\r
-            if (roundingDouble < 1.0d) {\r
-                double rawRoundedReciprocal = 1.0d/roundingDouble;\r
-                setRoundingDoubleReciprocal(rawRoundedReciprocal);\r
-            }\r
-            setInternalRoundingIncrement(new BigDecimal(newValue));\r
-        }\r
-    }\r
-\r
-\r
-    private void setRoundingDoubleReciprocal(double rawRoundedReciprocal) {\r
-        roundingDoubleReciprocal = Math.rint(rawRoundedReciprocal);\r
-        if (Math.abs(rawRoundedReciprocal - roundingDoubleReciprocal) > roundingIncrementEpsilon) {\r
-            roundingDoubleReciprocal = 0.0d;\r
-        }\r
-    }\r
-    \r
-    static final double roundingIncrementEpsilon = 0.000000001;\r
-    \r
-    /**\r
-     * Get the rounding mode.\r
-     * @return A rounding mode, between <code>BigDecimal.ROUND_UP</code>\r
-     * and <code>BigDecimal.ROUND_UNNECESSARY</code>.\r
-     * @see #setRoundingIncrement\r
-     * @see #getRoundingIncrement\r
-     * @see #setRoundingMode\r
-     * @see java.math.BigDecimal\r
-     * @stable ICU 2.0\r
-     */\r
-    public int getRoundingMode() {\r
-        return roundingMode;\r
-    }\r
-\r
-    /**\r
-     * Set the rounding mode.  This has no effect unless the rounding\r
-     * increment is greater than zero.\r
-     * @param roundingMode A rounding mode, between\r
-     * <code>BigDecimal.ROUND_UP</code> and\r
-     * <code>BigDecimal.ROUND_UNNECESSARY</code>.\r
-     * @exception IllegalArgumentException if <code>roundingMode</code>\r
-     * is unrecognized.\r
-     * @see #setRoundingIncrement\r
-     * @see #getRoundingIncrement\r
-     * @see #getRoundingMode\r
-     * @see java.math.BigDecimal\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setRoundingMode(int roundingMode) {\r
-        if (roundingMode < BigDecimal.ROUND_UP\r
-            || roundingMode > BigDecimal.ROUND_UNNECESSARY) {\r
-            throw new IllegalArgumentException("Invalid rounding mode: "\r
-                                               + roundingMode);\r
-        }\r
-\r
-        this.roundingMode = roundingMode;\r
-\r
-        if (getRoundingIncrement() == null) {\r
-            setRoundingIncrement(Math.pow(10.0,(double)-getMaximumFractionDigits()));\r
-        }\r
-    }\r
-\r
-    // [NEW]\r
-    /**\r
-     * Get the width to which the output of <code>format()</code> is padded.\r
-     * The width is counted in 16-bit code units.\r
-     * @return the format width, or zero if no padding is in effect\r
-     * @see #setFormatWidth\r
-     * @see #getPadCharacter\r
-     * @see #setPadCharacter\r
-     * @see #getPadPosition\r
-     * @see #setPadPosition\r
-     * @stable ICU 2.0\r
-     */\r
-    public int getFormatWidth() {\r
-        return formatWidth;\r
-    }\r
-\r
-    // [NEW]\r
-    /**\r
-     * Set the width to which the output of <code>format()</code> is padded.\r
-     * The width is counted in 16-bit code units.\r
-     * This method also controls whether padding is enabled.\r
-     * @param width the width to which to pad the result of\r
-     * <code>format()</code>, or zero to disable padding\r
-     * @exception IllegalArgumentException if <code>width</code> is < 0\r
-     * @see #getFormatWidth\r
-     * @see #getPadCharacter\r
-     * @see #setPadCharacter\r
-     * @see #getPadPosition\r
-     * @see #setPadPosition\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setFormatWidth(int width) {\r
-        if (width < 0) {\r
-            throw new IllegalArgumentException("Illegal format width");\r
-        }\r
-        formatWidth = width;\r
-    }\r
-\r
-    // [NEW]\r
-    /**\r
-     * Get the character used to pad to the format width.  The default is ' '.\r
-     * @return the pad character\r
-     * @see #setFormatWidth\r
-     * @see #getFormatWidth\r
-     * @see #setPadCharacter\r
-     * @see #getPadPosition\r
-     * @see #setPadPosition\r
-     * @stable ICU 2.0\r
-     */\r
-    public char getPadCharacter() {\r
-        return pad;\r
-    }\r
-\r
-    // [NEW]\r
-    /**\r
-     * Set the character used to pad to the format width.  If padding\r
-     * is not enabled, then this will take effect if padding is later\r
-     * enabled.\r
-     * @param padChar the pad character\r
-     * @see #setFormatWidth\r
-     * @see #getFormatWidth\r
-     * @see #getPadCharacter\r
-     * @see #getPadPosition\r
-     * @see #setPadPosition\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setPadCharacter(char padChar) {\r
-        pad = padChar;\r
-    }\r
-\r
-    // [NEW]\r
-    /**\r
-     * Get the position at which padding will take place.  This is the location\r
-     * at which padding will be inserted if the result of <code>format()</code>\r
-     * is shorter than the format width.\r
-     * @return the pad position, one of <code>PAD_BEFORE_PREFIX</code>,\r
-     * <code>PAD_AFTER_PREFIX</code>, <code>PAD_BEFORE_SUFFIX</code>, or\r
-     * <code>PAD_AFTER_SUFFIX</code>.\r
-     * @see #setFormatWidth\r
-     * @see #getFormatWidth\r
-     * @see #setPadCharacter\r
-     * @see #getPadCharacter\r
-     * @see #setPadPosition\r
-     * @see #PAD_BEFORE_PREFIX\r
-     * @see #PAD_AFTER_PREFIX\r
-     * @see #PAD_BEFORE_SUFFIX\r
-     * @see #PAD_AFTER_SUFFIX\r
-     * @stable ICU 2.0\r
-     */\r
-    public int getPadPosition() {\r
-        return padPosition;\r
-    }\r
-\r
-    // [NEW]\r
-    /**\r
-     * Set the position at which padding will take place.  This is the location\r
-     * at which padding will be inserted if the result of <code>format()</code>\r
-     * is shorter than the format width.  This has no effect unless padding is\r
-     * enabled.\r
-     * @param padPos the pad position, one of <code>PAD_BEFORE_PREFIX</code>,\r
-     * <code>PAD_AFTER_PREFIX</code>, <code>PAD_BEFORE_SUFFIX</code>, or\r
-     * <code>PAD_AFTER_SUFFIX</code>.\r
-     * @exception IllegalArgumentException if the pad position in\r
-     * unrecognized\r
-     * @see #setFormatWidth\r
-     * @see #getFormatWidth\r
-     * @see #setPadCharacter\r
-     * @see #getPadCharacter\r
-     * @see #getPadPosition\r
-     * @see #PAD_BEFORE_PREFIX\r
-     * @see #PAD_AFTER_PREFIX\r
-     * @see #PAD_BEFORE_SUFFIX\r
-     * @see #PAD_AFTER_SUFFIX\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setPadPosition(int padPos) {\r
-        if (padPos < PAD_BEFORE_PREFIX || padPos > PAD_AFTER_SUFFIX) {\r
-            throw new IllegalArgumentException("Illegal pad position");\r
-        }\r
-        padPosition = padPos;\r
-    }\r
-\r
-    // [NEW]\r
-    /**\r
-     * Return whether or not scientific notation is used.\r
-     * @return true if this object formats and parses scientific notation\r
-     * @see #setScientificNotation\r
-     * @see #getMinimumExponentDigits\r
-     * @see #setMinimumExponentDigits\r
-     * @see #isExponentSignAlwaysShown\r
-     * @see #setExponentSignAlwaysShown\r
-     * @stable ICU 2.0\r
-     */\r
-    public boolean isScientificNotation() {\r
-        return useExponentialNotation;\r
-    }\r
-\r
-    // [NEW]\r
-    /**\r
-     * Set whether or not scientific notation is used.  When scientific notation\r
-     * is used, the effective maximum number of integer digits is <= 8.  If the\r
-     * maximum number of integer digits is set to more than 8, the effective\r
-     * maximum will be 1.  This allows this call to generate a 'default' scientific\r
-     * number format without additional changes.\r
-     * @param useScientific true if this object formats and parses scientific\r
-     * notation\r
-     * @see #isScientificNotation\r
-     * @see #getMinimumExponentDigits\r
-     * @see #setMinimumExponentDigits\r
-     * @see #isExponentSignAlwaysShown\r
-     * @see #setExponentSignAlwaysShown\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setScientificNotation(boolean useScientific) {\r
-        useExponentialNotation = useScientific;\r
-    }\r
-\r
-    // [NEW]\r
-    /**\r
-     * Return the minimum exponent digits that will be shown.\r
-     * @return the minimum exponent digits that will be shown\r
-     * @see #setScientificNotation\r
-     * @see #isScientificNotation\r
-     * @see #setMinimumExponentDigits\r
-     * @see #isExponentSignAlwaysShown\r
-     * @see #setExponentSignAlwaysShown\r
-     * @stable ICU 2.0\r
-     */\r
-    public byte getMinimumExponentDigits() {\r
-        return minExponentDigits;\r
-    }\r
-    \r
-    // [NEW]\r
-    /**\r
-     * Set the minimum exponent digits that will be shown.  This has no\r
-     * effect unless scientific notation is in use.\r
-     * @param minExpDig a value >= 1 indicating the fewest exponent digits\r
-     * that will be shown\r
-     * @exception IllegalArgumentException if <code>minExpDig</code> < 1\r
-     * @see #setScientificNotation\r
-     * @see #isScientificNotation\r
-     * @see #getMinimumExponentDigits\r
-     * @see #isExponentSignAlwaysShown\r
-     * @see #setExponentSignAlwaysShown\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setMinimumExponentDigits(byte minExpDig) {\r
-        if (minExpDig < 1) {\r
-            throw new IllegalArgumentException("Exponent digits must be >= 1");\r
-        }\r
-        minExponentDigits = minExpDig;\r
-    }\r
-\r
-    // [NEW]\r
-    /**\r
-     * Return whether the exponent sign is always shown.\r
-     * @return true if the exponent is always prefixed with either the\r
-     * localized minus sign or the localized plus sign, false if only negative\r
-     * exponents are prefixed with the localized minus sign.\r
-     * @see #setScientificNotation\r
-     * @see #isScientificNotation\r
-     * @see #setMinimumExponentDigits\r
-     * @see #getMinimumExponentDigits\r
-     * @see #setExponentSignAlwaysShown\r
-     * @stable ICU 2.0\r
-     */\r
-    public boolean isExponentSignAlwaysShown() {\r
-        return exponentSignAlwaysShown;\r
-    }\r
-\r
-    // [NEW]\r
-    /**\r
-     * Set whether the exponent sign is always shown.  This has no effect\r
-     * unless scientific notation is in use.\r
-     * @param expSignAlways true if the exponent is always prefixed with either\r
-     * the localized minus sign or the localized plus sign, false if only\r
-     * negative exponents are prefixed with the localized minus sign.\r
-     * @see #setScientificNotation\r
-     * @see #isScientificNotation\r
-     * @see #setMinimumExponentDigits\r
-     * @see #getMinimumExponentDigits\r
-     * @see #isExponentSignAlwaysShown\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setExponentSignAlwaysShown(boolean expSignAlways) {\r
-        exponentSignAlwaysShown = expSignAlways;\r
-    }\r
-\r
-    /**\r
-     * Return the grouping size. Grouping size is the number of digits between\r
-     * grouping separators in the integer portion of a number.  For example,\r
-     * in the number "123,456.78", the grouping size is 3.\r
-     * @see #setGroupingSize\r
-     * @see NumberFormat#isGroupingUsed\r
-     * @see DecimalFormatSymbols#getGroupingSeparator\r
-     * @stable ICU 2.0\r
-     */\r
-    public int getGroupingSize () {\r
-        return groupingSize;\r
-    }\r
-\r
-    /**\r
-     * Set the grouping size. Grouping size is the number of digits between\r
-     * grouping separators in the integer portion of a number.  For example,\r
-     * in the number "123,456.78", the grouping size is 3.\r
-     * @see #getGroupingSize\r
-     * @see NumberFormat#setGroupingUsed\r
-     * @see DecimalFormatSymbols#setGroupingSeparator\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setGroupingSize (int newValue) {\r
-        groupingSize = (byte)newValue;\r
-    }\r
-\r
-    // [NEW]\r
-    /**\r
-     * Return the secondary grouping size. In some locales one\r
-     * grouping interval is used for the least significant integer\r
-     * digits (the primary grouping size), and another is used for all\r
-     * others (the secondary grouping size).  A formatter supporting a\r
-     * secondary grouping size will return a positive integer unequal\r
-     * to the primary grouping size returned by\r
-     * <code>getGroupingSize()</code>.  For example, if the primary\r
-     * grouping size is 4, and the secondary grouping size is 2, then\r
-     * the number 123456789 formats as "1,23,45,6789", and the pattern\r
-     * appears as "#,##,###0".\r
-     * @return the secondary grouping size, or a value less than\r
-     * one if there is none\r
-     * @see #setSecondaryGroupingSize\r
-     * @see NumberFormat#isGroupingUsed\r
-     * @see DecimalFormatSymbols#getGroupingSeparator\r
-     * @stable ICU 2.0\r
-     */\r
-    public int getSecondaryGroupingSize () {\r
-        return groupingSize2;\r
-    }\r
-\r
-    // [NEW]\r
-    /**\r
-     * Set the secondary grouping size. If set to a value less than 1,\r
-     * then secondary grouping is turned off, and the primary grouping\r
-     * size is used for all intervals, not just the least significant.\r
-     * @see #getSecondaryGroupingSize\r
-     * @see NumberFormat#setGroupingUsed\r
-     * @see DecimalFormatSymbols#setGroupingSeparator\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setSecondaryGroupingSize (int newValue) {\r
-        groupingSize2 = (byte)newValue;\r
-    }\r
-\r
-    // [NEW]\r
-    /**\r
-     * Returns the MathContext\r
-     * used by this format. \r
-     * @return desired MathContext\r
-     * @see #mathContext\r
-     * @see #getMathContext\r
-     * @draft ICU 4.2\r
-     * @provisional This API might change or be removed in a future release.\r
-     */\r
-    public MathContext getMathContextICU() {\r
-        return mathContext;\r
-    }\r
-\r
-//#if defined(FOUNDATION10) || defined(J2SE13) || defined(J2SE14) || defined(ECLIPSE_FRAGMENT)\r
-//#else\r
-    // [NEW]\r
-    /**\r
-     * Returns the MathContext\r
-     * used by this format. \r
-     * @return desired MathContext\r
-     * @see #mathContext\r
-     * @see #getMathContext\r
-     * @draft ICU 4.2\r
-     * @provisional This API might change or be removed in a future release.\r
-     */\r
-    public java.math.MathContext getMathContext()\r
-    {\r
-        try\r
-        {\r
-            // don't allow multiple references\r
-            return mathContext == null ?\r
-                   null :\r
-                   new java.math.MathContext(mathContext.getDigits(),\r
-                                             java.math.RoundingMode.valueOf(mathContext.getRoundingMode()));\r
-        }\r
-        catch (Exception foo)\r
-        {\r
-            return null; // should never happen\r
-        }\r
-    }\r
-//#endif\r
-\r
-    // [NEW]\r
-    /**\r
-     * Sets the MathContext used by this format.\r
-     * @param newValue desired MathContext\r
-     * @see #mathContext\r
-     * @see #getMathContext\r
-     * @draft ICU 4.2\r
-     * @provisional This API might change or be removed in a future release.\r
-     */\r
-    public void setMathContextICU(MathContext newValue) {\r
-        mathContext = newValue;\r
-    }\r
-\r
-//#if defined(FOUNDATION10) || defined(J2SE13) || defined(J2SE14) || defined(ECLIPSE_FRAGMENT)\r
-//#else\r
-    // [NEW]\r
-    /**\r
-     * Sets the MathContext used by this format.\r
-     * @param newValue desired MathContext\r
-     * @see #mathContext\r
-     * @see #getMathContext\r
-     * @draft ICU 4.2\r
-     * @provisional This API might change or be removed in a future release.\r
-     */\r
-    public void setMathContext(java.math.MathContext newValue)\r
-    {\r
-        mathContext = new MathContext(newValue.getPrecision(),\r
-                                      MathContext.SCIENTIFIC,\r
-                                      false,\r
-                                      (newValue.getRoundingMode()).ordinal()\r
-                                      );\r
-    }\r
-//#endif\r
-\r
-    /**\r
-     * Allows you to get the behavior of the decimal separator with integers.\r
-     * (The decimal separator will always appear with decimals.)\r
-     * <P>Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345\r
-     * @stable ICU 2.0\r
-     */\r
-    public boolean isDecimalSeparatorAlwaysShown() {\r
-        return decimalSeparatorAlwaysShown;\r
-    }\r
-\r
-    /**\r
-     * Allows you to set the behavior of the decimal separator with integers.\r
-     * (The decimal separator will always appear with decimals.)\r
-     *\r
-     * <p>This only affects formatting, and only where\r
-     * there might be no digits after the decimal point, e.g.,\r
-     * if true,  3456.00 -> "3,456."\r
-     * if false, 3456.00 -> "3456"\r
-     * This is independent of parsing.  If you want parsing to stop at the decimal\r
-     * point, use setParseIntegerOnly.\r
-     *\r
-     * <P>Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setDecimalSeparatorAlwaysShown(boolean newValue) {\r
-        decimalSeparatorAlwaysShown = newValue;\r
-    }\r
-\r
-    /**\r
-     * Returns a copy of the CurrencyPluralInfo \r
-     * used by this format. \r
-     * It might return null if the decimal format is not a plural type \r
-     * currency decimal format.\r
-     * Plural type currency decimal format means either\r
-     * the pattern in the decimal format contains 3 currency signs,\r
-     * or the decimal format is initialized with PLURALCURRENCYSTYLE.\r
-     * @return desired CurrencyPluralInfo\r
-     * @see CurrencyPluralInfo\r
-     * @draft ICU 4.2\r
-     * @provisional This API might change or be removed in a future release.\r
-     */\r
-    public CurrencyPluralInfo getCurrencyPluralInfo() {\r
-        try {\r
-            // don't allow multiple references\r
-            return currencyPluralInfo == null ? \r
-                   null :\r
-                   (CurrencyPluralInfo) currencyPluralInfo.clone();\r
-        } catch (Exception foo) {\r
-            return null; // should never happen\r
-        }\r
-    }\r
-\r
-\r
-    /**\r
-     * Sets the CurrencyPluralInfo used by this format.  The\r
-     * format uses a copy of the provided information.\r
-     * @param newInfo desired CurrencyPluralInfo\r
-     * @see CurrencyPluralInfo\r
-     * @draft ICU 4.2\r
-     * @provisional This API might change or be removed in a future release.\r
-     */\r
-    public void setCurrencyPluralInfo(CurrencyPluralInfo newInfo) {\r
-        currencyPluralInfo = (CurrencyPluralInfo) newInfo.clone();\r
-        isReadyForParsing = false;\r
-    }\r
-\r
-    /**\r
-     * Standard override; no change in semantics.\r
-     * @stable ICU 2.0\r
-     */\r
-    public Object clone() {\r
-        try {\r
-            DecimalFormat other = (DecimalFormat) super.clone();\r
-            other.symbols = (DecimalFormatSymbols) symbols.clone();\r
-            other.digitList = new DigitList(); // fix for JB#5358\r
-            if (currencyPluralInfo != null) {\r
-                other.currencyPluralInfo = (CurrencyPluralInfo)currencyPluralInfo.clone();\r
-            }\r
-            /*\r
-             * TODO: We need to figure out whether we share a single copy\r
-             * of DigitList by multiple cloned copies.  format/subformat\r
-             * are designed to use a single instance, but parse/subparse\r
-             * implementation is not. \r
-             */\r
-            return other;\r
-        } catch (Exception e) {\r
-            throw new IllegalStateException();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Overrides equals\r
-     * @stable ICU 2.0\r
-     */\r
-    public boolean equals(Object obj)\r
-    {\r
-        if (obj == null) return false;\r
-        if (!super.equals(obj)) return false; // super does class check\r
-\r
-        DecimalFormat other = (DecimalFormat) obj;\r
-        /* Add the comparison of the four new added fields ,they are\r
-         * posPrefixPattern, posSuffixPattern, negPrefixPattern, negSuffixPattern.\r
-         * [Richard/GCL]\r
-         */\r
-        // following are added to accomodate changes for currency plural format.\r
-        return currencySignCount == other.currencySignCount\r
-            && (style != NumberFormat.PLURALCURRENCYSTYLE ||\r
-                   equals(posPrefixPattern, other.posPrefixPattern)\r
-                   && equals(posSuffixPattern, other.posSuffixPattern)\r
-                   && equals(negPrefixPattern, other.negPrefixPattern)\r
-                   && equals(negSuffixPattern, other.negSuffixPattern))\r
-            && multiplier == other.multiplier\r
-            && groupingSize == other.groupingSize\r
-            && groupingSize2 == other.groupingSize2\r
-            && decimalSeparatorAlwaysShown == other.decimalSeparatorAlwaysShown\r
-            && useExponentialNotation == other.useExponentialNotation\r
-            && (!useExponentialNotation ||\r
-                minExponentDigits == other.minExponentDigits)\r
-            && useSignificantDigits == other.useSignificantDigits\r
-            && (!useSignificantDigits ||\r
-                minSignificantDigits == other.minSignificantDigits &&\r
-                maxSignificantDigits == other.maxSignificantDigits)\r
-            && symbols.equals(other.symbols) \r
-            && Utility.objectEquals(currencyPluralInfo, other.currencyPluralInfo);\r
-    }\r
-\r
-    //method to unquote the strings and compare\r
-    private boolean equals(String pat1, String pat2){\r
-        if (pat1 == null || pat2 == null) {\r
-            return (pat1 == null && pat2 == null);\r
-        }\r
-        //fast path\r
-        if(pat1.equals(pat2)){\r
-            return true;\r
-        }\r
-        return unquote(pat1).equals(unquote(pat2));\r
-    }\r
-    private String unquote(String pat){\r
-        StringBuffer buf = new StringBuffer(pat.length());\r
-        int i=0;\r
-        while(i<pat.length()){\r
-            char ch = pat.charAt(i++);\r
-            if(ch!=QUOTE){\r
-                buf.append(ch);\r
-            }\r
-        }\r
-        return buf.toString();\r
-    }\r
-//      protected void handleToString(StringBuffer buf) {\r
-//          buf.append("\nposPrefixPattern: '" + posPrefixPattern + "'\n");\r
-//          buf.append("positivePrefix: '" + positivePrefix + "'\n");\r
-//          buf.append("posSuffixPattern: '" + posSuffixPattern + "'\n");\r
-//          buf.append("positiveSuffix: '" + positiveSuffix + "'\n");\r
-//          buf.append("negPrefixPattern: '" + com.ibm.icu.impl.Utility.format1ForSource(negPrefixPattern) + "'\n");\r
-//          buf.append("negativePrefix: '" + com.ibm.icu.impl.Utility.format1ForSource(negativePrefix) + "'\n");\r
-//          buf.append("negSuffixPattern: '" + negSuffixPattern + "'\n");\r
-//          buf.append("negativeSuffix: '" + negativeSuffix + "'\n");\r
-//          buf.append("multiplier: '" + multiplier + "'\n");\r
-//          buf.append("groupingSize: '" + groupingSize + "'\n");\r
-//          buf.append("groupingSize2: '" + groupingSize2 + "'\n");\r
-//          buf.append("decimalSeparatorAlwaysShown: '" + decimalSeparatorAlwaysShown + "'\n");\r
-//          buf.append("useExponentialNotation: '" + useExponentialNotation + "'\n");\r
-//          buf.append("minExponentDigits: '" + minExponentDigits + "'\n");\r
-//          buf.append("useSignificantDigits: '" + useSignificantDigits + "'\n");\r
-//          buf.append("minSignificantDigits: '" + minSignificantDigits + "'\n");\r
-//          buf.append("maxSignificantDigits: '" + maxSignificantDigits + "'\n");           \r
-//          buf.append("symbols: '" + symbols + "'");\r
-//      }\r
-\r
-    /**\r
-     * Overrides hashCode\r
-     * @stable ICU 2.0\r
-     */\r
-    public int hashCode() {\r
-        return super.hashCode() * 37 + positivePrefix.hashCode();\r
-        // just enough fields for a reasonable distribution\r
-    }\r
-\r
-    /**\r
-     * Synthesizes a pattern string that represents the current state\r
-     * of this Format object.\r
-     * @see #applyPattern\r
-     * @stable ICU 2.0\r
-     */\r
-    public String toPattern() {\r
-        if (style == NumberFormat.PLURALCURRENCYSTYLE) {\r
-            // the prefix or suffix pattern might not be defined yet,\r
-            // so they can not be synthesized,\r
-            // instead, get them directly.\r
-            // but it might not be the actual pattern used in formatting.\r
-            // the actual pattern used in formatting depends on the \r
-            // formatted number's plural count.\r
-            return formatPattern;\r
-        }\r
-        return toPattern( false );\r
-    }\r
-\r
-    /**\r
-     * Synthesizes a localized pattern string that represents the current\r
-     * state of this Format object.\r
-     * @see #applyPattern\r
-     * @stable ICU 2.0\r
-     */\r
-    public String toLocalizedPattern() {\r
-        if (style == NumberFormat.PLURALCURRENCYSTYLE) {\r
-            return formatPattern;\r
-        }\r
-        return toPattern( true );\r
-    }\r
-\r
-    /**\r
-     * Expand the affix pattern strings into the expanded affix strings.  If any\r
-     * affix pattern string is null, do not expand it.  This method should be\r
-     * called any time the symbols or the affix patterns change in order to keep\r
-     * the expanded affix strings up to date.\r
-     * This method also will be called before formatting if format currency\r
-     * plural names, since the plural name is not a static one, it is \r
-     * based on the currency plural count, the affix will be known only\r
-     * after the currency plural count is know. \r
-     * In which case, the parameter\r
-     * 'pluralCount' will be a non-null currency plural count.\r
-     * In all other cases, the 'pluralCount' is null, which means \r
-     * it is not needed.\r
-     */\r
-    //Bug 4212072 [Richard/GCL]\r
-    private void expandAffixes(String pluralCount) {\r
-        // expandAffix() will set currencyChoice to a non-null value if\r
-        // appropriate AND if it is null.\r
-        currencyChoice = null;\r
-\r
-        // Reuse one StringBuffer for better performance\r
-        StringBuffer buffer = new StringBuffer();\r
-        if (posPrefixPattern != null) {\r
-            expandAffix(posPrefixPattern, pluralCount, buffer, false);\r
-            positivePrefix = buffer.toString();\r
-        }\r
-        if (posSuffixPattern != null) {\r
-            expandAffix(posSuffixPattern, pluralCount, buffer, false);\r
-            positiveSuffix = buffer.toString();\r
-        }\r
-        if (negPrefixPattern != null) {\r
-            expandAffix(negPrefixPattern, pluralCount, buffer, false);\r
-            negativePrefix = buffer.toString();\r
-        }\r
-        if (negSuffixPattern != null) {\r
-            expandAffix(negSuffixPattern, pluralCount, buffer, false);\r
-            negativeSuffix = buffer.toString();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Expand an affix pattern into an affix string.  All characters in\r
-     * the pattern are literal unless bracketed by QUOTEs.  The\r
-     * following characters outside QUOTE are recognized:\r
-     * PATTERN_PERCENT, PATTERN_PER_MILLE, PATTERN_MINUS, and\r
-     * CURRENCY_SIGN.  If CURRENCY_SIGN is doubled, it is interpreted as\r
-     * an international currency sign.  If CURRENCY_SIGN is tripled,\r
-     * it is interpreted as currency plural long names, such as "US Dollars".\r
-     * Any other character outside\r
-     * QUOTE represents itself.  Quoted text must be well-formed.\r
-     *\r
-     * This method is used in two distinct ways.  First, it is used to expand\r
-     * the stored affix patterns into actual affixes.  For this usage, doFormat\r
-     * must be false.  Second, it is used to expand the stored affix patterns\r
-     * given a specific number (doFormat == true), for those rare cases in\r
-     * which a currency format references a ChoiceFormat (e.g., en_IN display\r
-     * name for INR).  The number itself is taken from digitList.\r
-     *\r
-     * When used in the first way, this method has a side effect: It sets\r
-     * currencyChoice to a ChoiceFormat object, if the currency's display name\r
-     * in this locale is a ChoiceFormat pattern (very rare).  It only does this\r
-     * if currencyChoice is null to start with.\r
-     *\r
-     * @param pattern the non-null, possibly empty pattern\r
-     * @param pluralCount the plural count. It is only used for currency\r
-     *                    plural format. In which case, it is the plural\r
-     *                    count of the currency amount. For example,\r
-     *                    in en_US, it is the singular "one", or the plural\r
-     *                    "other". For all other cases, it is null, and\r
-     *                    is not being used.\r
-     * @param buffer a scratch StringBuffer; its contents will be lost\r
-     * @param doFormat if false, then the pattern will be expanded, and if a\r
-     * currency symbol is encountered that expands to a ChoiceFormat, the\r
-     * currencyChoice member variable will be initialized if it is null.  If\r
-     * doFormat is true, then it is assumed that the currencyChoice has been\r
-     * created, and it will be used to format the value in digitList.\r
-     * @return the expanded equivalent of pattern\r
-     */\r
-    //Bug 4212072 [Richard/GCL]\r
-    private void expandAffix(String pattern, \r
-                             String pluralCount, \r
-                             StringBuffer buffer,\r
-                             boolean doFormat) {\r
-        buffer.setLength(0);\r
-        for (int i=0; i<pattern.length(); ) {\r
-            char c = pattern.charAt(i++);\r
-            if (c == QUOTE) {\r
-                for (;;) {\r
-                    int j = pattern.indexOf(QUOTE, i);\r
-                    if (j == i) {\r
-                        buffer.append(QUOTE);\r
-                        i = j+1;\r
-                        break;\r
-                    } else if (j > i) {\r
-                        buffer.append(pattern.substring(i, j));\r
-                        i = j+1;\r
-                        if (i<pattern.length() &&\r
-                            pattern.charAt(i)==QUOTE) {\r
-                            buffer.append(QUOTE);\r
-                            ++i;\r
-                            // loop again\r
-                        } else {\r
-                            break;\r
-                        }\r
-                    } else {\r
-                        // Unterminated quote; should be caught by apply\r
-                        // pattern.\r
-                        throw new RuntimeException();\r
-                    }\r
-                }\r
-                continue;\r
-            }\r
-\r
-            switch (c) {\r
-            case CURRENCY_SIGN:\r
-                // As of ICU 2.2 we use the currency object, and\r
-                // ignore the currency symbols in the DFS, unless\r
-                // we have a null currency object.  This occurs if\r
-                // resurrecting a pre-2.2 object or if the user\r
-                // sets a custom DFS.\r
-                boolean intl = i<pattern.length() &&\r
-                    pattern.charAt(i) == CURRENCY_SIGN;\r
-                boolean plural = false;\r
-                if (intl) {\r
-                    ++i;\r
-                    if (i<pattern.length() &&\r
-                        pattern.charAt(i) == CURRENCY_SIGN) {\r
-                        plural = true;\r
-                        intl = false;\r
-                        ++i;\r
-                    }\r
-                }\r
-                String s = null;\r
-                Currency currency = getCurrency();\r
-                if (currency != null) {\r
-                    // plural name is only needed when pluralCount != null,\r
-                    // which means when formatting currency plural names.\r
-                    // For other cases, pluralCount == null,\r
-                    // and plural names are not needed.\r
-                    if (plural && pluralCount != null) {\r
-                        boolean isChoiceFormat[] = new boolean[1];\r
-                        s = currency.getName(symbols.getULocale(), \r
-                                             Currency.PLURAL_LONG_NAME, \r
-                                             pluralCount, \r
-                                             isChoiceFormat);\r
-                    }\r
-                    else if (!intl) {\r
-                        boolean isChoiceFormat[] = new boolean[1];\r
-                        s = currency.getName(symbols.getULocale(),\r
-                                             Currency.SYMBOL_NAME,\r
-                                             isChoiceFormat);\r
-                        if (isChoiceFormat[0]) {\r
-                            // Two modes here: If doFormat is false, we set up\r
-                            // currencyChoice.  If doFormat is true, we use the\r
-                            // previously created currencyChoice to format the\r
-                            // value in digitList.\r
-                            if (!doFormat) {\r
-                                // If the currency is handled by a ChoiceFormat,\r
-                                // then we're not going to use the expanded\r
-                                // patterns.  Instantiate the ChoiceFormat and\r
-                                // return.\r
-                                if (currencyChoice == null) {\r
-                                    currencyChoice = new ChoiceFormat(s);\r
-                                }\r
-                                // We could almost return null or "" here, since the\r
-                                // expanded affixes are almost not used at all\r
-                                // in this situation.  However, one method --\r
-                                // toPattern() -- still does use the expanded\r
-                                // affixes, in order to set up a padding\r
-                                // pattern.  We use the CURRENCY_SIGN as a\r
-                                // placeholder.\r
-                                s = String.valueOf(CURRENCY_SIGN);\r
-                            } else {\r
-                                FieldPosition pos = new FieldPosition(0); // ignored\r
-                                currencyChoice.format(digitList.getDouble(), buffer, pos);\r
-                                continue;\r
-                            }\r
-                        }\r
-                    } else {\r
-                        s = currency.getCurrencyCode();\r
-                    }\r
-                } else {\r
-                    s = intl ? symbols.getInternationalCurrencySymbol()\r
-                        : symbols.getCurrencySymbol();\r
-                }\r
-                buffer.append(s);\r
-                continue;\r
-            case PATTERN_PERCENT:\r
-                c = symbols.getPercent();\r
-                break;\r
-            case PATTERN_PER_MILLE:\r
-                c = symbols.getPerMill();\r
-                break;\r
-            case PATTERN_MINUS:\r
-                c = symbols.getMinusSign();\r
-                break;\r
-            }\r
-            buffer.append(c);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Append an affix to the given StringBuffer.\r
-     * @param buf buffer to append to\r
-     * @param isNegative\r
-     * @param isPrefix\r
-     */\r
-    private int appendAffix(StringBuffer buf, boolean isNegative,\r
-            boolean isPrefix, boolean parseAttr) {\r
-        if (currencyChoice != null) {\r
-            String affixPat = null;\r
-            if (isPrefix) {\r
-                affixPat = isNegative ? negPrefixPattern : posPrefixPattern;\r
-            } else {\r
-                affixPat = isNegative ? negSuffixPattern : posSuffixPattern;\r
-            }\r
-            StringBuffer affixBuf = new StringBuffer();\r
-            expandAffix(affixPat, null, affixBuf, true);\r
-            buf.append(affixBuf.toString());\r
-            return affixBuf.length();\r
-        }\r
-\r
-        String affix = null;\r
-        if (isPrefix) {\r
-            affix = isNegative ? negativePrefix : positivePrefix;\r
-        } else {\r
-            affix = isNegative ? negativeSuffix : positiveSuffix;\r
-        }\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-        // [Spark/CDL] Invoke formatAffix2Attribute to add attributes for affix\r
-        if (parseAttr) {\r
-            int offset = affix.indexOf(symbols.getCurrencySymbol());\r
-            if (-1 == offset) {\r
-                offset = affix.indexOf(symbols.getPercent());\r
-                if(-1 == offset) {\r
-                    offset = 0;\r
-                }\r
-            }\r
-            formatAffix2Attribute(affix, buf.length() + offset, buf.length()\r
-                    + affix.length());\r
-        }\r
-//#endif\r
-        buf.append(affix);\r
-        return affix.length();\r
-    }\r
-\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-    /*\r
-     * [Spark/CDL] This is a newly added method, used to add attributes for\r
-     * prefix and suffix.\r
-     */\r
-    private void formatAffix2Attribute(String affix, int begin, int end) {\r
-        // [Spark/CDL] It is the invoker's responsibility to ensure that, before\r
-        // the invocation of\r
-        // this method, attributes is not null.\r
-        // if( attributes == null ) return;\r
-        if (affix.indexOf(symbols.getCurrencySymbol()) > -1) {\r
-            addAttribute(Field.CURRENCY, begin, end);\r
-        } else if (affix.indexOf(symbols.getMinusSign()) > -1) {\r
-            addAttribute(Field.SIGN, begin, end);\r
-        } else if (affix.indexOf(symbols.getPercent()) > -1) {\r
-            addAttribute(Field.PERCENT, begin, end);\r
-        } else if (affix.indexOf(symbols.getPerMill()) > -1) {\r
-            addAttribute(Field.PERMILLE, begin, end);\r
-        }\r
-    }\r
-//#endif\r
-\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-    /*\r
-     * [Spark/CDL] Use this method to add attribute.\r
-     */\r
-    private void addAttribute(Field field, int begin, int end) {\r
-        FieldPosition pos = new FieldPosition(field);\r
-        pos.setBeginIndex(begin);\r
-        pos.setEndIndex(end);\r
-        attributes.add(pos);\r
-    }\r
-//#endif\r
-\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-    /**\r
-     * Format the object to an attributed string, and return the corresponding iterator\r
-     * Overrides superclass method.\r
-     * @stable ICU 3.6\r
-     */\r
-    // [Spark/CDL] \r
-    public AttributedCharacterIterator formatToCharacterIterator(Object obj) {\r
-        if (!(obj instanceof Number))\r
-            throw new IllegalArgumentException();\r
-        Number number = (Number) obj;\r
-        StringBuffer text = null;\r
-        attributes.clear();\r
-        if (obj instanceof BigInteger) {\r
-            text = format((BigInteger) number, new StringBuffer(),\r
-                    new FieldPosition(0), true);\r
-        } else if (obj instanceof java.math.BigDecimal) {\r
-            text = format((java.math.BigDecimal) number, new StringBuffer(),\r
-                    new FieldPosition(0), true);\r
-        } else if (obj instanceof Double) {\r
-            text = format(number.doubleValue(), new StringBuffer(),\r
-                    new FieldPosition(0), true);\r
-        } else if (obj instanceof Integer || obj instanceof Long) {\r
-            text = format(number.longValue(), new StringBuffer(),\r
-                    new FieldPosition(0), true);\r
-        }\r
-\r
-        AttributedString as = new AttributedString(text.toString());\r
-\r
-        // add NumberFormat field attributes to the AttributedString\r
-        for (int i = 0; i < attributes.size(); i++) {\r
-            FieldPosition pos = (FieldPosition) attributes.get(i);\r
-            Format.Field attribute = pos.getFieldAttribute();\r
-            as.addAttribute(attribute, attribute, pos.getBeginIndex(), pos\r
-                    .getEndIndex());\r
-        }\r
-\r
-        // return the CharacterIterator from AttributedString\r
-        return as.getIterator();\r
-    }\r
-//#endif\r
-    /**\r
-     * Append an affix pattern to the given StringBuffer.  Localize unquoted\r
-     * specials.\r
-     */\r
-    private void appendAffixPattern(StringBuffer buffer,\r
-                                    boolean isNegative, boolean isPrefix,\r
-                                    boolean localized) {\r
-        String affixPat = null;\r
-        if (isPrefix) {\r
-            affixPat = isNegative ? negPrefixPattern : posPrefixPattern;\r
-        } else {\r
-            affixPat = isNegative ? negSuffixPattern : posSuffixPattern;\r
-        }\r
-\r
-        // When there is a null affix pattern, we use the affix itself.\r
-        if (affixPat == null) {\r
-            String affix = null;\r
-            if (isPrefix) {\r
-                affix = isNegative ? negativePrefix : positivePrefix;\r
-            } else {\r
-                affix = isNegative ? negativeSuffix : positiveSuffix;\r
-            }\r
-            // Do this crudely for now:  Wrap everything in quotes.\r
-            buffer.append(QUOTE);\r
-            for (int i=0; i<affix.length(); ++i) {\r
-                char ch = affix.charAt(i);\r
-                if (ch == QUOTE) {\r
-                    buffer.append(ch);\r
-                }\r
-                buffer.append(ch);\r
-            }\r
-            buffer.append(QUOTE);\r
-            return;\r
-        }\r
-\r
-        if (!localized) {\r
-            buffer.append(affixPat);\r
-        } else {\r
-            int i, j;\r
-            for (i=0; i<affixPat.length(); ++i) {\r
-                char ch = affixPat.charAt(i);\r
-                switch (ch) {\r
-                case QUOTE:\r
-                    j = affixPat.indexOf(QUOTE, i+1);\r
-                    if (j < 0) {\r
-                        throw new IllegalArgumentException("Malformed affix pattern: " + affixPat);\r
-                    }\r
-                    buffer.append(affixPat.substring(i, j+1));\r
-                    i = j;\r
-                    continue;\r
-                case PATTERN_PER_MILLE:\r
-                    ch = symbols.getPerMill();\r
-                    break;\r
-                case PATTERN_PERCENT:\r
-                    ch = symbols.getPercent();\r
-                    break;\r
-                case PATTERN_MINUS:\r
-                    ch = symbols.getMinusSign();\r
-                    break;\r
-                }\r
-                //check if char is same as any other symbol\r
-                if(ch==symbols.getDecimalSeparator() ||\r
-                   ch==symbols.getGroupingSeparator() ){\r
-                    buffer.append(QUOTE);\r
-                    buffer.append(ch);\r
-                    buffer.append(QUOTE);\r
-                }else{\r
-                    buffer.append(ch);\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * <strong><font face=helvetica color=red>CHANGED</font></strong>\r
-     * Does the real work of generating a pattern.\r
-     */\r
-    private String toPattern(boolean localized) {\r
-        StringBuffer result = new StringBuffer();\r
-        char zero = localized ? symbols.getZeroDigit() : PATTERN_ZERO_DIGIT;\r
-        char digit = localized ? symbols.getDigit() : PATTERN_DIGIT;\r
-        char sigDigit = 0;\r
-        boolean useSigDig = areSignificantDigitsUsed();\r
-        if (useSigDig) {\r
-            sigDigit = localized ? symbols.getSignificantDigit() : PATTERN_SIGNIFICANT_DIGIT;\r
-        }\r
-        char group = localized ? symbols.getGroupingSeparator()\r
-                               : PATTERN_GROUPING_SEPARATOR;\r
-        int i;\r
-        int roundingDecimalPos = 0; // Pos of decimal in roundingDigits\r
-        String roundingDigits = null;\r
-        int padPos = (formatWidth > 0) ? padPosition : -1;\r
-        String padSpec = (formatWidth > 0)\r
-            ? new StringBuffer(2).\r
-                append(localized ? symbols.getPadEscape() : PATTERN_PAD_ESCAPE).\r
-                append(pad).toString()\r
-            : null;\r
-        if (roundingIncrementICU != null) {\r
-            i = roundingIncrementICU.scale();\r
-            roundingDigits = roundingIncrementICU.movePointRight(i).toString();\r
-            roundingDecimalPos = roundingDigits.length() - i;\r
-        }\r
-        for (int part=0; part<2; ++part) {\r
-            // variable not used int partStart = result.length();\r
-            if (padPos == PAD_BEFORE_PREFIX) {\r
-                result.append(padSpec);\r
-            }\r
-            /* Use original symbols read from resources in pattern\r
-             * eg. use "\u00A4" instead of "$" in Locale.US [Richard/GCL]\r
-             */\r
-            appendAffixPattern(result, part!=0, true, localized);\r
-            if (padPos == PAD_AFTER_PREFIX) {\r
-                result.append(padSpec);\r
-            }\r
-            int sub0Start = result.length();\r
-            int g = isGroupingUsed() ? Math.max(0, groupingSize) : 0;\r
-            if (g > 0 && groupingSize2 > 0 && groupingSize2 != groupingSize) {\r
-                g += groupingSize2;\r
-            }\r
-            int maxDig = 0, minDig = 0, maxSigDig = 0;\r
-            if (useSigDig) {\r
-                minDig = getMinimumSignificantDigits();\r
-                maxDig = maxSigDig = getMaximumSignificantDigits();\r
-            } else {\r
-                minDig = getMinimumIntegerDigits();\r
-                maxDig = getMaximumIntegerDigits();\r
-            }\r
-            if (useExponentialNotation) {\r
-                if (maxDig > MAX_SCIENTIFIC_INTEGER_DIGITS) {\r
-                    maxDig = 1;\r
-                }\r
-            } else if (useSigDig) {\r
-                maxDig = Math.max(maxDig, g+1);\r
-            } else {\r
-                maxDig = Math.max(Math.max(g, getMinimumIntegerDigits()),\r
-                                  roundingDecimalPos) + 1;\r
-            }\r
-            for (i = maxDig; i > 0; --i) {\r
-                if (!useExponentialNotation && i<maxDig &&\r
-                    isGroupingPosition(i)) {\r
-                    result.append(group);\r
-                }\r
-                if (useSigDig) {\r
-                    //  #@,@###   (maxSigDig == 5, minSigDig == 2)\r
-                    //  65 4321   (1-based pos, count from the right)\r
-                    // Use # if pos > maxSigDig or 1 <= pos <= (maxSigDig - minSigDig)\r
-                    // Use @ if (maxSigDig - minSigDig) < pos <= maxSigDig\r
-                    result.append((maxSigDig >= i && i > (maxSigDig - minDig)) ? sigDigit : digit);\r
-                } else {\r
-                    if (roundingDigits != null) {\r
-                        int pos = roundingDecimalPos - i;\r
-                        if (pos >= 0 && pos < roundingDigits.length()) {\r
-                            result.append((char) (roundingDigits.charAt(pos) - '0' + zero));\r
-                            continue;\r
-                        }\r
-                    }\r
-                    result.append(i<=minDig ? zero : digit);\r
-                }\r
-            }\r
-            if (!useSigDig) {\r
-                if (getMaximumFractionDigits() > 0 || decimalSeparatorAlwaysShown) {\r
-                    result.append(localized ? symbols.getDecimalSeparator() :\r
-                                  PATTERN_DECIMAL_SEPARATOR);\r
-                }\r
-                int pos = roundingDecimalPos;\r
-                for (i = 0; i < getMaximumFractionDigits(); ++i) {\r
-                    if (roundingDigits != null &&\r
-                        pos < roundingDigits.length()) {\r
-                        result.append(pos < 0 ? zero :\r
-                                      (char) (roundingDigits.charAt(pos) - '0' + zero));\r
-                        ++pos;\r
-                        continue;\r
-                    }\r
-                    result.append(i<getMinimumFractionDigits() ? zero : digit);\r
-                }\r
-            }\r
-            if (useExponentialNotation) {\r
-                if(localized ){\r
-                    result.append(symbols.getExponentSeparator() );\r
-                }else{\r
-                    result.append(PATTERN_EXPONENT);\r
-                }\r
-                if (exponentSignAlwaysShown) {\r
-                    result.append(localized ? symbols.getPlusSign() :\r
-                                  PATTERN_PLUS_SIGN);\r
-                }\r
-                for (i=0; i<minExponentDigits; ++i) {\r
-                    result.append(zero);\r
-                }\r
-            }\r
-            if (padSpec != null && !useExponentialNotation) {\r
-                int add = formatWidth - result.length() + sub0Start\r
-                    - ((part == 0)\r
-                       ? positivePrefix.length() + positiveSuffix.length()\r
-                       : negativePrefix.length() + negativeSuffix.length());\r
-                while (add > 0) {\r
-                    result.insert(sub0Start, digit);\r
-                    ++maxDig;\r
-                    --add;\r
-                    // Only add a grouping separator if we have at least\r
-                    // 2 additional characters to be added, so we don't\r
-                    // end up with ",###".\r
-                    if (add>1 && isGroupingPosition(maxDig)) {\r
-                        result.insert(sub0Start, group);\r
-                        --add;                        \r
-                    }\r
-                }\r
-            }\r
-            if (padPos == PAD_BEFORE_SUFFIX) {\r
-                result.append(padSpec);\r
-            }\r
-            /* Use original symbols read from resources in pattern\r
-             * eg. use "\u00A4" instead of "$" in Locale.US [Richard/GCL]\r
-             */\r
-            appendAffixPattern(result, part!=0, false, localized);\r
-            if (padPos == PAD_AFTER_SUFFIX) {\r
-                result.append(padSpec);\r
-            }\r
-            if (part == 0) {\r
-                if (negativeSuffix.equals(positiveSuffix) &&\r
-                    negativePrefix.equals( PATTERN_MINUS + positivePrefix)) {\r
-                    break;\r
-                } else {\r
-                    result.append(localized ? symbols.getPatternSeparator() :\r
-                                  PATTERN_SEPARATOR);\r
-                }\r
-            }\r
-        }\r
-        return result.toString();\r
-    }\r
-\r
-    /**\r
-     * Apply the given pattern to this Format object.  A pattern is a\r
-     * short-hand specification for the various formatting properties.\r
-     * These properties can also be changed individually through the\r
-     * various setter methods.\r
-     * <p>\r
-     * There is no limit to integer digits are set\r
-     * by this routine, since that is the typical end-user desire;\r
-     * use setMaximumInteger if you want to set a real value.\r
-     * For negative numbers, use a second pattern, separated by a semicolon\r
-     * <P>Example "#,#00.0#" -> 1,234.56\r
-     * <P>This means a minimum of 2 integer digits, 1 fraction digit, and\r
-     * a maximum of 2 fraction digits.\r
-     * <p>Example: "#,#00.0#;(#,#00.0#)" for negatives in parentheses.\r
-     * <p>In negative patterns, the minimum and maximum counts are ignored;\r
-     * these are presumed to be set in the positive pattern.\r
-     * @stable ICU 2.0\r
-     */\r
-    public void applyPattern( String pattern ) {\r
-        applyPattern( pattern, false );\r
-    }\r
-\r
-    /**\r
-     * Apply the given pattern to this Format object.  The pattern\r
-     * is assumed to be in a localized notation. A pattern is a\r
-     * short-hand specification for the various formatting properties.\r
-     * These properties can also be changed individually through the\r
-     * various setter methods.\r
-     * <p>\r
-     * There is no limit to integer digits are set\r
-     * by this routine, since that is the typical end-user desire;\r
-     * use setMaximumInteger if you want to set a real value.\r
-     * For negative numbers, use a second pattern, separated by a semicolon\r
-     * <P>Example "#,#00.0#" -> 1,234.56\r
-     * <P>This means a minimum of 2 integer digits, 1 fraction digit, and\r
-     * a maximum of 2 fraction digits.\r
-     * <p>Example: "#,#00.0#;(#,#00.0#)" for negatives in parantheses.\r
-     * <p>In negative patterns, the minimum and maximum counts are ignored;\r
-     * these are presumed to be set in the positive pattern.\r
-     * @stable ICU 2.0\r
-     */\r
-    public void applyLocalizedPattern( String pattern ) {\r
-        applyPattern( pattern, true );\r
-    }\r
-\r
-   \r
-    /**\r
-     * <strong><font face=helvetica color=red>CHANGED</font></strong>\r
-     * Does the real work of applying a pattern.\r
-     */\r
-    private void applyPattern(String pattern, boolean localized) {\r
-        applyPatternWithoutExpandAffix(pattern, localized);\r
-        expandAffixAdjustWidth(null);\r
-    }\r
-\r
-    private void expandAffixAdjustWidth(String pluralCount) {\r
-        /*Bug 4212072\r
-          Update the affix strings according to symbols in order to keep\r
-          the affix strings up to date.\r
-          [Richard/GCL]\r
-        */\r
-        expandAffixes(pluralCount);\r
-\r
-        // Now that we have the actual prefix and suffix, fix up formatWidth\r
-        if (formatWidth > 0) {\r
-            formatWidth += positivePrefix.length() + positiveSuffix.length();\r
-        }\r
-    }\r
-\r
-    private void applyPatternWithoutExpandAffix(String pattern, boolean localized) {\r
-        char zeroDigit         = PATTERN_ZERO_DIGIT; // '0'\r
-        char sigDigit          = PATTERN_SIGNIFICANT_DIGIT; // '@'\r
-        char groupingSeparator = PATTERN_GROUPING_SEPARATOR;\r
-        char decimalSeparator  = PATTERN_DECIMAL_SEPARATOR;\r
-        char percent           = PATTERN_PERCENT;\r
-        char perMill           = PATTERN_PER_MILLE;\r
-        char digit             = PATTERN_DIGIT; // '#'\r
-        char separator         = PATTERN_SEPARATOR;\r
-        String exponent        = String.valueOf(PATTERN_EXPONENT);\r
-        char plus              = PATTERN_PLUS_SIGN;\r
-        char padEscape         = PATTERN_PAD_ESCAPE;\r
-        char minus             = PATTERN_MINUS; //Bug 4212072 [Richard/GCL]\r
-        if (localized) {\r
-            zeroDigit         = symbols.getZeroDigit();\r
-            sigDigit          = symbols.getSignificantDigit();\r
-            groupingSeparator = symbols.getGroupingSeparator();\r
-            decimalSeparator  = symbols.getDecimalSeparator();\r
-            percent           = symbols.getPercent();\r
-            perMill           = symbols.getPerMill();\r
-            digit             = symbols.getDigit();\r
-            separator         = symbols.getPatternSeparator();\r
-            exponent          = symbols.getExponentSeparator();\r
-            plus              = symbols.getPlusSign();\r
-            padEscape         = symbols.getPadEscape();\r
-            minus             = symbols.getMinusSign(); //Bug 4212072 [Richard/GCL]\r
-        }\r
-        char nineDigit = (char) (zeroDigit + 9);\r
-\r
-        boolean gotNegative = false;\r
-\r
-        int pos = 0;\r
-        // Part 0 is the positive pattern.  Part 1, if present, is the negative\r
-        // pattern.\r
-        for (int part=0; part<2 && pos<pattern.length(); ++part) {\r
-            // The subpart ranges from 0 to 4: 0=pattern proper, 1=prefix,\r
-            // 2=suffix, 3=prefix in quote, 4=suffix in quote.  Subpart 0 is\r
-            // between the prefix and suffix, and consists of pattern\r
-            // characters.  In the prefix and suffix, percent, permille, and\r
-            // currency symbols are recognized and translated.\r
-            int subpart = 1, sub0Start = 0, sub0Limit = 0, sub2Limit = 0;\r
-\r
-            // It's important that we don't change any fields of this object\r
-            // prematurely.  We set the following variables for the multiplier,\r
-            // grouping, etc., and then only change the actual object fields if\r
-            // everything parses correctly.  This also lets us register\r
-            // the data from part 0 and ignore the part 1, except for the\r
-            // prefix and suffix.\r
-            StringBuffer prefix = new StringBuffer();\r
-            StringBuffer suffix = new StringBuffer();\r
-            int decimalPos = -1;\r
-            int multpl = 1;\r
-            int digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0, sigDigitCount = 0;\r
-            byte groupingCount = -1;\r
-            byte groupingCount2 = -1;\r
-            int padPos = -1;\r
-            char padChar = 0;\r
-            int incrementPos = -1;\r
-            long incrementVal = 0;\r
-            byte expDigits = -1;\r
-            boolean expSignAlways = false;\r
-\r
-            // The affix is either the prefix or the suffix.\r
-            StringBuffer affix = prefix;\r
-\r
-            int start = pos;\r
-\r
-        PARTLOOP:\r
-            for (; pos < pattern.length(); ++pos) {\r
-                char ch = pattern.charAt(pos);\r
-                switch (subpart) {\r
-                case 0: // Pattern proper subpart (between prefix & suffix)\r
-                    // Process the digits, decimal, and grouping characters.  We\r
-                    // record five pieces of information.  We expect the digits\r
-                    // to occur in the pattern ####00.00####, and we record the\r
-                    // number of left digits, zero (central) digits, and right\r
-                    // digits.  The position of the last grouping character is\r
-                    // recorded (should be somewhere within the first two blocks\r
-                    // of characters), as is the position of the decimal point,\r
-                    // if any (should be in the zero digits).  If there is no\r
-                    // decimal point, then there should be no right digits.\r
-                    if (ch == digit) {\r
-                        if (zeroDigitCount > 0 || sigDigitCount > 0) {\r
-                            ++digitRightCount;\r
-                        } else {\r
-                            ++digitLeftCount;\r
-                        }\r
-                        if (groupingCount >= 0 && decimalPos < 0) {\r
-                            ++groupingCount;\r
-                        }\r
-                    } else if ((ch >= zeroDigit && ch <= nineDigit) ||\r
-                               ch == sigDigit) {\r
-                        if (digitRightCount > 0) {\r
-                            patternError("Unexpected '" + ch + '\'', pattern);\r
-                        }\r
-                        if (ch == sigDigit) {\r
-                            ++sigDigitCount;\r
-                        } else {\r
-                            ++zeroDigitCount;\r
-                            if (ch != zeroDigit) {\r
-                                int p = digitLeftCount + zeroDigitCount\r
-                                    + digitRightCount;\r
-                                if (incrementPos >= 0) {\r
-                                    while (incrementPos < p) {\r
-                                        incrementVal *= 10;\r
-                                        ++incrementPos;\r
-                                    }\r
-                                } else {\r
-                                    incrementPos = p;\r
-                                }\r
-                                incrementVal += ch - zeroDigit;\r
-                            }\r
-                        }\r
-                        if (groupingCount >= 0 && decimalPos < 0) {\r
-                            ++groupingCount;\r
-                        }\r
-                    } else if (ch == groupingSeparator) {\r
-                        /*Bug 4212072\r
-                          process the Localized pattern like "'Fr. '#'##0.05;'Fr.-'#'##0.05"\r
-                          (Locale="CH", groupingSeparator == QUOTE)                          \r
-                          [Richard/GCL]\r
-                        */\r
-                        if (ch == QUOTE && (pos+1) < pattern.length()) {\r
-                            char after = pattern.charAt(pos+1);\r
-                            if (!(after == digit || (after >= zeroDigit && after <= nineDigit))) {\r
-                                // A quote outside quotes indicates either the opening\r
-                                // quote or two quotes, which is a quote literal.  That is,\r
-                                // we have the first quote in 'do' or o''clock.\r
-                                if (after == QUOTE) {\r
-                                    ++pos;\r
-                                    // Fall through to append(ch)\r
-                                } else {\r
-                                    if (groupingCount < 0) {\r
-                                        subpart = 3; // quoted prefix subpart\r
-                                    } else {\r
-                                      // Transition to suffix subpart\r
-                                      subpart = 2; // suffix subpart\r
-                                      affix = suffix;\r
-                                      sub0Limit = pos--;\r
-                                    }\r
-                                    continue;\r
-                                }\r
-                            }\r
-                        }\r
-                        \r
-                        if (decimalPos >= 0) {\r
-                            patternError("Grouping separator after decimal", pattern);\r
-                        }\r
-                        groupingCount2 = groupingCount;\r
-                        groupingCount = 0;\r
-                    } else if (ch == decimalSeparator) {\r
-                        if (decimalPos >= 0) {\r
-                            patternError("Multiple decimal separators", pattern);\r
-                        }\r
-                        // Intentionally incorporate the digitRightCount,\r
-                        // even though it is illegal for this to be > 0\r
-                        // at this point.  We check pattern syntax below.\r
-                        decimalPos = digitLeftCount + zeroDigitCount + digitRightCount;\r
-                    } else {\r
-                        if (pattern.regionMatches(pos, exponent, 0, exponent.length())) {\r
-                            if (expDigits >= 0) {\r
-                                patternError("Multiple exponential symbols", pattern);\r
-                            }\r
-                            if (groupingCount >= 0) {\r
-                                patternError("Grouping separator in exponential", pattern);\r
-                            }\r
-                            pos += exponent.length();\r
-                            // Check for positive prefix\r
-                            if (pos < pattern.length()\r
-                                && pattern.charAt(pos) == plus) {\r
-                                expSignAlways = true;\r
-                                ++pos;\r
-                            }\r
-                            // Use lookahead to parse out the exponential part of the\r
-                            // pattern, then jump into suffix subpart.\r
-                            expDigits = 0;\r
-                            while (pos < pattern.length() &&\r
-                                   pattern.charAt(pos) == zeroDigit) {\r
-                                ++expDigits;\r
-                                ++pos;\r
-                            }\r
-                            \r
-                            // 1. Require at least one mantissa pattern digit\r
-                            // 2. Disallow "#+ @" in mantissa\r
-                            // 3. Require at least one exponent pattern digit\r
-                            if (((digitLeftCount + zeroDigitCount) < 1 &&\r
-                                 (sigDigitCount + digitRightCount) < 1) ||\r
-                                (sigDigitCount > 0 && digitLeftCount > 0) ||\r
-                                expDigits < 1) {\r
-                                patternError("Malformed exponential", pattern);\r
-                            }\r
-                        }\r
-                        // Transition to suffix subpart\r
-                        subpart = 2; // suffix subpart\r
-                        affix = suffix;\r
-                        sub0Limit = pos--; // backup: for() will increment\r
-                        continue;\r
-                    }\r
-                    break;\r
-                case 1: // Prefix subpart\r
-                case 2: // Suffix subpart\r
-                    // Process the prefix / suffix characters\r
-                    // Process unquoted characters seen in prefix or suffix\r
-                    // subpart.\r
-                    \r
-                    // Several syntax characters implicitly begins the\r
-                    // next subpart if we are in the prefix; otherwise\r
-                    // they are illegal if unquoted.\r
-                    if (ch == digit ||\r
-                        ch == groupingSeparator ||\r
-                        ch == decimalSeparator ||\r
-                        (ch >= zeroDigit && ch <= nineDigit) ||\r
-                        ch == sigDigit) {\r
-                        // Any of these characters implicitly begins the\r
-                        // next subpart if we are in the prefix\r
-                        if (subpart == 1) { // prefix subpart\r
-                            subpart = 0; // pattern proper subpart\r
-                            sub0Start = pos--; // Reprocess this character\r
-                            continue;\r
-                        } else if (ch == QUOTE) {\r
-                            /*Bug 4212072\r
-                              process the Localized pattern like "'Fr. '#'##0.05;'Fr.-'#'##0.05"\r
-                              (Locale="CH", groupingSeparator == QUOTE)                          \r
-                              [Richard/GCL]\r
-                            */\r
-                            // A quote outside quotes indicates either the opening\r
-                            // quote or two quotes, which is a quote literal.  That is,\r
-                            // we have the first quote in 'do' or o''clock.\r
-                            if ((pos+1) < pattern.length() &&\r
-                                pattern.charAt(pos+1) == QUOTE) {\r
-                                ++pos;\r
-                                affix.append(ch);\r
-                            } else {\r
-                                subpart += 2; // open quote\r
-                            }\r
-                            continue;\r
-                        }\r
-                        patternError("Unquoted special character '" + ch + '\'', pattern);\r
-                    } else if (ch == CURRENCY_SIGN) {\r
-                        // Use lookahead to determine if the currency sign is\r
-                        // doubled or not.\r
-                        boolean doubled = (pos + 1) < pattern.length() &&\r
-                            pattern.charAt(pos + 1) == CURRENCY_SIGN;\r
-                        /*Bug 4212072\r
-                         To meet the need of expandAffix(String, StirngBuffer)\r
-                         [Richard/GCL]\r
-                        */\r
-                        if (doubled) {\r
-                            ++pos; // Skip over the doubled character\r
-                            affix.append(ch); // append two: one here, one below\r
-                            if ((pos + 1) < pattern.length() &&\r
-                                pattern.charAt(pos + 1) == CURRENCY_SIGN) {\r
-                                ++pos; // Skip over the tripled character\r
-                                affix.append(ch); // append again\r
-                                currencySignCount = CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT;\r
-                            } else {\r
-                                currencySignCount = CURRENCY_SIGN_COUNT_IN_ISO_FORMAT;\r
-                            } \r
-                        } else {\r
-                            currencySignCount = CURRENCY_SIGN_COUNT_IN_SYMBOL_FORMAT;\r
-                        }\r
-                        // Fall through to append(ch)\r
-                    } else if (ch == QUOTE) {\r
-                        // A quote outside quotes indicates either the opening\r
-                        // quote or two quotes, which is a quote literal.  That is,\r
-                        // we have the first quote in 'do' or o''clock.\r
-                        if((pos+1) < pattern.length()&&\r
-                            pattern.charAt(pos+1)==QUOTE){\r
-                            ++pos;\r
-                            affix.append(ch); // append two: one here, one below\r
-                        }else{\r
-                            subpart += 2; // open quote\r
-                        }\r
-                        // Fall through to append(ch)\r
-                    } else if (ch == separator) {\r
-                        // Don't allow separators in the prefix, and don't allow\r
-                        // separators in the second pattern (part == 1).\r
-                        if (subpart == 1 || part == 1) {\r
-                            patternError("Unquoted special character '" + ch + '\'', pattern);\r
-                        }\r
-                        sub2Limit = pos++;\r
-                        break PARTLOOP; // Go to next part\r
-                    } else if (ch == percent || ch == perMill) {\r
-                        // Next handle characters which are appended directly.\r
-                        if (multpl != 1) {\r
-                            patternError("Too many percent/permille characters", pattern);\r
-                        }\r
-                        multpl = (ch == percent) ? 100 : 1000;\r
-                        // Convert to non-localized pattern\r
-                        ch = (ch == percent) ? PATTERN_PERCENT : PATTERN_PER_MILLE;\r
-                        // Fall through to append(ch)\r
-                    } else if (ch == minus) {\r
-                        // Convert to non-localized pattern\r
-                        ch = PATTERN_MINUS;\r
-                        // Fall through to append(ch)\r
-                    } else if (ch == padEscape) {\r
-                        if (padPos >= 0) {\r
-                            patternError("Multiple pad specifiers", pattern);\r
-                        }\r
-                        if ((pos+1) == pattern.length()) {\r
-                            patternError("Invalid pad specifier", pattern);\r
-                        }\r
-                        padPos = pos++; // Advance past pad char\r
-                        padChar = pattern.charAt(pos);\r
-                        continue;\r
-                    }\r
-                    affix.append(ch);\r
-                    break;\r
-                case 3: // Prefix subpart, in quote\r
-                case 4: // Suffix subpart, in quote\r
-                    // A quote within quotes indicates either the closing\r
-                    // quote or two quotes, which is a quote literal.  That is,\r
-                    // we have the second quote in 'do' or 'don''t'.\r
-                    if (ch == QUOTE) {\r
-                        if ((pos+1) < pattern.length() &&\r
-                            pattern.charAt(pos+1) == QUOTE) {\r
-                            ++pos; \r
-                            affix.append(ch);\r
-                        } else {\r
-                            subpart -= 2; // close quote\r
-                        }\r
-                        // Fall through to append(ch)\r
-                    }\r
-                    // NOTE: In ICU 2.2 there was code here to parse quoted\r
-                    // percent and permille characters _within quotes_ and give\r
-                    // them special meaning.  This is incorrect, since quoted\r
-                    // characters are literals without special meaning.\r
-                    affix.append(ch);\r
-                    break;                    \r
-                }\r
-            }\r
-            \r
-            if (subpart == 3 || subpart == 4) {\r
-                patternError("Unterminated quote", pattern);\r
-            }\r
-\r
-            if (sub0Limit == 0) {\r
-                sub0Limit = pattern.length();\r
-            }\r
-\r
-            if (sub2Limit == 0) {\r
-                sub2Limit = pattern.length();\r
-            }\r
-\r
-            /* Handle patterns with no '0' pattern character.  These patterns\r
-             * are legal, but must be recodified to make sense.  "##.###" ->\r
-             * "#0.###".  ".###" -> ".0##".\r
-             *\r
-             * We allow patterns of the form "####" to produce a zeroDigitCount\r
-             * of zero (got that?); although this seems like it might make it\r
-             * possible for format() to produce empty strings, format() checks\r
-             * for this condition and outputs a zero digit in this situation.\r
-             * Having a zeroDigitCount of zero yields a minimum integer digits\r
-             * of zero, which allows proper round-trip patterns.  We don't want\r
-             * "#" to become "#0" when toPattern() is called (even though that's\r
-             * what it really is, semantically).\r
-             */\r
-            if (zeroDigitCount == 0 && sigDigitCount == 0 &&\r
-                digitLeftCount > 0 && decimalPos >= 0) {\r
-                // Handle "###.###" and "###." and ".###"\r
-                int n = decimalPos;\r
-                if (n == 0) ++n; // Handle ".###"\r
-                digitRightCount = digitLeftCount - n;\r
-                digitLeftCount = n - 1;\r
-                zeroDigitCount = 1;\r
-            }\r
-\r
-            // Do syntax checking on the digits, decimal points, and quotes.\r
-            if ((decimalPos < 0 && digitRightCount > 0 && sigDigitCount == 0) ||\r
-                (decimalPos >= 0 &&\r
-                 (sigDigitCount > 0 ||\r
-                  decimalPos < digitLeftCount ||\r
-                  decimalPos > (digitLeftCount + zeroDigitCount))) ||\r
-                groupingCount == 0 || groupingCount2 == 0 ||\r
-                (sigDigitCount > 0 && zeroDigitCount > 0) ||\r
-                subpart > 2) { // subpart > 2 == unmatched quote\r
-                patternError("Malformed pattern", pattern);\r
-            }\r
-\r
-            // Make sure pad is at legal position before or after affix.\r
-            if (padPos >= 0) {\r
-                if (padPos == start) {\r
-                    padPos = PAD_BEFORE_PREFIX;\r
-                } else if (padPos+2 == sub0Start) {\r
-                    padPos = PAD_AFTER_PREFIX;\r
-                } else if (padPos == sub0Limit) {\r
-                    padPos = PAD_BEFORE_SUFFIX;\r
-                } else if (padPos+2 == sub2Limit) {\r
-                    padPos = PAD_AFTER_SUFFIX;\r
-                } else {\r
-                    patternError("Illegal pad position", pattern);\r
-                }\r
-            }\r
-\r
-            if (part == 0) {\r
-                // Set negative affixes temporarily to match the positive\r
-                // affixes.  Fix this up later after processing both parts.\r
-                /*Bug 4212072\r
-                  To meet the need of expandAffix(String, StirngBuffer)\r
-                  [Richard/GCL]\r
-                */\r
-                posPrefixPattern = negPrefixPattern = prefix.toString();\r
-                posSuffixPattern = negSuffixPattern = suffix.toString();\r
-\r
-                useExponentialNotation = (expDigits >= 0);\r
-                if (useExponentialNotation) {\r
-                    minExponentDigits = expDigits;\r
-                    exponentSignAlwaysShown = expSignAlways;\r
-                }\r
-                int digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount;\r
-                // The effectiveDecimalPos is the position the decimal is at or\r
-                // would be at if there is no decimal.  Note that if\r
-                // decimalPos<0, then digitTotalCount == digitLeftCount +\r
-                // zeroDigitCount.\r
-                int effectiveDecimalPos = decimalPos >= 0 ? decimalPos : digitTotalCount;\r
-                boolean useSigDig = (sigDigitCount > 0);\r
-                setSignificantDigitsUsed(useSigDig);\r
-                if (useSigDig) {\r
-                    setMinimumSignificantDigits(sigDigitCount);\r
-                    setMaximumSignificantDigits(sigDigitCount + digitRightCount);\r
-                } else {\r
-                    int minInt = effectiveDecimalPos - digitLeftCount;\r
-                    setMinimumIntegerDigits(minInt);\r
-                    /*Upper limit on integer and fraction digits for a Java double\r
-                      [Richard/GCL]\r
-                    */\r
-                    setMaximumIntegerDigits(useExponentialNotation\r
-                        ? digitLeftCount + minInt : DOUBLE_INTEGER_DIGITS);\r
-                    setMaximumFractionDigits(decimalPos >= 0\r
-                        ? (digitTotalCount - decimalPos) : 0);\r
-                    setMinimumFractionDigits(decimalPos >= 0\r
-                        ? (digitLeftCount + zeroDigitCount - decimalPos) : 0);\r
-                }\r
-                setGroupingUsed(groupingCount > 0);\r
-                this.groupingSize = (groupingCount > 0) ? groupingCount : 0;\r
-                this.groupingSize2 = (groupingCount2 > 0 && groupingCount2 != groupingCount)\r
-                    ? groupingCount2 : 0;\r
-                this.multiplier = multpl;\r
-                setDecimalSeparatorAlwaysShown(decimalPos == 0\r
-                        || decimalPos == digitTotalCount);\r
-                if (padPos >= 0) {\r
-                    padPosition = padPos;\r
-                    formatWidth = sub0Limit - sub0Start; // to be fixed up below\r
-                    pad = padChar;\r
-                } else {\r
-                    formatWidth = 0;\r
-                }\r
-                if (incrementVal != 0) {\r
-                    // BigDecimal scale cannot be negative (even though\r
-                    // this makes perfect sense), so we need to handle this.\r
-                    int scale = incrementPos - effectiveDecimalPos;\r
-                    roundingIncrementICU =\r
-                        BigDecimal.valueOf(incrementVal, scale > 0 ? scale : 0);\r
-                    if (scale < 0) {\r
-                        roundingIncrementICU =\r
-                            roundingIncrementICU.movePointRight(-scale);\r
-                    }\r
-                    setRoundingDouble();\r
-                    roundingMode = BigDecimal.ROUND_HALF_EVEN;\r
-                } else {\r
-                    setRoundingIncrement((BigDecimal)null);\r
-                }\r
-            } else {\r
-                /*Bug 4212072\r
-                  To meet the need of expandAffix(String, StirngBuffer)\r
-                  [Richard/GCL]\r
-                */\r
-                negPrefixPattern = prefix.toString();\r
-                negSuffixPattern = suffix.toString();\r
-                gotNegative = true;\r
-            }\r
-        }\r
-\r
-        /*Bug 4140009\r
-          Process the empty pattern\r
-          [Richard/GCL]\r
-        */\r
-        if (pattern.length() == 0) {\r
-            posPrefixPattern = posSuffixPattern = "";\r
-            setMinimumIntegerDigits(0);\r
-            setMaximumIntegerDigits(DOUBLE_INTEGER_DIGITS);\r
-            setMinimumFractionDigits(0);\r
-            setMaximumFractionDigits(DOUBLE_FRACTION_DIGITS);\r
-        }\r
-        \r
-        // If there was no negative pattern, or if the negative pattern is\r
-        // identical to the positive pattern, then prepend the minus sign to the\r
-        // positive pattern to form the negative pattern.\r
-        /*Bug 4212072\r
-          To meet the need of expandAffix(String, StirngBuffer)\r
-          [Richard/GCL]\r
-        */\r
-        if (!gotNegative ||\r
-            (negPrefixPattern.equals(posPrefixPattern)\r
-             && negSuffixPattern.equals(posSuffixPattern))) {\r
-            negSuffixPattern = posSuffixPattern;\r
-            negPrefixPattern = PATTERN_MINUS + posPrefixPattern;\r
-        }\r
-        setLocale(null, null);\r
-        // save the pattern\r
-        formatPattern = pattern;\r
-        // initialize currencyPluralInfo if needed \r
-        if (currencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT &&\r
-            currencyPluralInfo == null) { \r
-            currencyPluralInfo = new CurrencyPluralInfo(symbols.getLocale());\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Centralizes the setting of the roundingDouble and roundingDoubleReciprocal.\r
-     */\r
-    private void setRoundingDouble() {\r
-        if (roundingIncrementICU == null) {\r
-            roundingDouble = 0.0d;\r
-            roundingDoubleReciprocal = 0.0d;\r
-        } else {\r
-            roundingDouble = roundingIncrementICU.doubleValue();\r
-            setRoundingDoubleReciprocal(BigDecimal.ONE.divide(roundingIncrementICU,BigDecimal.ROUND_HALF_EVEN).doubleValue());\r
-        }\r
-    }\r
-\r
-    private void patternError(String msg, String pattern) {\r
-        throw new IllegalArgumentException(msg + " in pattern \"" + pattern + '"');\r
-    }\r
-\r
-    /*Rewrite the following 4 "set" methods\r
-      Upper limit on integer and fraction digits for a Java double \r
-      [Richard/GCL]\r
-    */\r
-    /**\r
-     * Sets the maximum number of digits allowed in the integer portion of a\r
-     * number. This override limits the integer digit count to 309.\r
-     * @see NumberFormat#setMaximumIntegerDigits\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setMaximumIntegerDigits(int newValue) {\r
-        super.setMaximumIntegerDigits(Math.min(newValue, DOUBLE_INTEGER_DIGITS));\r
-    }\r
-\r
-    /**\r
-     * Sets the minimum number of digits allowed in the integer portion of a\r
-     * number. This override limits the integer digit count to 309.\r
-     * @see NumberFormat#setMinimumIntegerDigits\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setMinimumIntegerDigits(int newValue) {\r
-        super.setMinimumIntegerDigits(Math.min(newValue, DOUBLE_INTEGER_DIGITS));\r
-    }\r
-\r
-    /**\r
-     * Returns the minimum number of significant digits that will be\r
-     * displayed. This value has no effect unless areSignificantDigitsUsed()\r
-     * returns true.\r
-     * @return the fewest significant digits that will be shown\r
-     * @stable ICU 3.0\r
-     */\r
-    public int getMinimumSignificantDigits() {\r
-        return minSignificantDigits;\r
-    }\r
-\r
-    /**\r
-     * Returns the maximum number of significant digits that will be\r
-     * displayed. This value has no effect unless areSignificantDigitsUsed()\r
-     * returns true.\r
-     * @return the most significant digits that will be shown\r
-     * @stable ICU 3.0\r
-     */\r
-    public int getMaximumSignificantDigits() {\r
-        return maxSignificantDigits;\r
-    }\r
-\r
-    /**\r
-     * Sets the minimum number of significant digits that will be\r
-     * displayed.  If <code>min</code> is less than one then it is set\r
-     * to one.  If the maximum significant digits count is less than\r
-     * <code>min</code>, then it is set to <code>min</code>. This\r
-     * value has no effect unless areSignificantDigitsUsed() returns true.\r
-     * @param min the fewest significant digits to be shown \r
-     * @stable ICU 3.0\r
-     */\r
-    public void setMinimumSignificantDigits(int min) {\r
-        if (min < 1) {\r
-            min = 1;   \r
-        }\r
-        // pin max sig dig to >= min\r
-        int max = Math.max(maxSignificantDigits, min);\r
-        minSignificantDigits = min;\r
-        maxSignificantDigits = max;\r
-    }\r
-\r
-    /**\r
-     * Sets the maximum number of significant digits that will be\r
-     * displayed.  If <code>max</code> is less than one then it is set\r
-     * to one.  If the minimum significant digits count is greater\r
-     * than <code>max</code>, then it is set to <code>max</code>. This\r
-     * value has no effect unless areSignificantDigitsUsed() returns true.\r
-     * @param max the most significant digits to be shown \r
-     * @stable ICU 3.0\r
-     */\r
-    public void setMaximumSignificantDigits(int max) {\r
-        if (max < 1) {\r
-            max = 1;\r
-        }\r
-        // pin min sig dig to 1..max\r
-        int min = Math.min(minSignificantDigits, max);\r
-        minSignificantDigits = min;\r
-        maxSignificantDigits = max;\r
-    }\r
-\r
-    /**\r
-     * Returns true if significant digits are in use or false if\r
-     * integer and fraction digit counts are in use.\r
-     * @return true if significant digits are in use\r
-     * @stable ICU 3.0\r
-     */\r
-    public boolean areSignificantDigitsUsed() {\r
-        return useSignificantDigits;\r
-    }\r
-\r
-    /**\r
-     * Sets whether significant digits are in use, or integer and\r
-     * fraction digit counts are in use.\r
-     * @param useSignificantDigits true to use significant digits, or\r
-     * false to use integer and fraction digit counts\r
-     * @stable ICU 3.0\r
-     */\r
-    public void setSignificantDigitsUsed(boolean useSignificantDigits) {\r
-        this.useSignificantDigits = useSignificantDigits;\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 through the application of a new pattern.\r
-     * @param theCurrency new currency object to use.  Must not be\r
-     * null.\r
-     * @stable ICU 2.2\r
-     */\r
-    public void setCurrency(Currency theCurrency) {\r
-        // If we are a currency format, then modify our affixes to\r
-        // encode the currency symbol for the given currency in our\r
-        // locale, and adjust the decimal digits and rounding for the\r
-        // given currency.\r
-\r
-        super.setCurrency(theCurrency);\r
-        if (theCurrency != null) {\r
-            boolean[] isChoiceFormat = new boolean[1];\r
-            String s = theCurrency.getName(symbols.getULocale(),\r
-                    Currency.SYMBOL_NAME,\r
-                    isChoiceFormat);\r
-                symbols.setCurrencySymbol(s);\r
-                symbols.setInternationalCurrencySymbol(theCurrency.getCurrencyCode());\r
-        }\r
-\r
-        if (currencySignCount > 0) {\r
-            if (theCurrency != null) {\r
-                setRoundingIncrement(theCurrency.getRoundingIncrement());\r
-                int d = theCurrency.getDefaultFractionDigits();\r
-                setMinimumFractionDigits(d);\r
-                setMaximumFractionDigits(d);\r
-            }\r
-            expandAffixes(null);\r
-        }\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
-     * @internal\r
-     * @deprecated This API is ICU internal only.\r
-     */\r
-    protected Currency getEffectiveCurrency() {\r
-        Currency c = getCurrency();\r
-        if (c == null) {\r
-            c = Currency.getInstance(symbols.getInternationalCurrencySymbol());\r
-        }\r
-        return c;\r
-    }\r
-\r
-    /**\r
-     * Sets the maximum number of digits allowed in the fraction portion of a\r
-     * number. This override limits the fraction digit count to 340.\r
-     * @see NumberFormat#setMaximumFractionDigits\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setMaximumFractionDigits(int newValue) {\r
-        super.setMaximumFractionDigits(Math.min(newValue, DOUBLE_FRACTION_DIGITS));\r
-    }\r
-\r
-    /**\r
-     * Sets the minimum number of digits allowed in the fraction portion of a\r
-     * number. This override limits the fraction digit count to 340.\r
-     * @see NumberFormat#setMinimumFractionDigits\r
-     * @stable ICU 2.0\r
-     */\r
-    public void setMinimumFractionDigits(int newValue) {\r
-        super.setMinimumFractionDigits(Math.min(newValue, DOUBLE_FRACTION_DIGITS));\r
-    }\r
-\r
-    /**\r
-     * Sets whether {@link #parse(String, ParsePosition)} method returns BigDecimal.\r
-     * The default value is false.\r
-     * @param value true if {@link #parse(String, ParsePosition)} method returns\r
-     * BigDecimal.\r
-     * @stable ICU 3.6\r
-     */\r
-    public void setParseBigDecimal(boolean value) {\r
-        parseBigDecimal = value;\r
-    }\r
-\r
-    /**\r
-     * Returns whether {@link #parse(String, ParsePosition)} method returns BigDecimal.\r
-     * @return true if {@link #parse(String, ParsePosition)} method returns BigDecimal.\r
-     * @stable ICU 3.6\r
-     */\r
-    public boolean isParseBigDecimal() {\r
-        return parseBigDecimal;\r
-    }\r
-\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-    private void writeObject(ObjectOutputStream stream) throws IOException {\r
-// Doug, do we need this anymore?\r
-//            if (roundingIncrementICU != null) {\r
-//                roundingIncrement = roundingIncrementICU.toBigDecimal();\r
-//            }\r
-\r
-        // Ticket#6449\r
-        // Format.Field instances are not serializable.  When formatToCharacterIterator\r
-        // is called, attributes (ArrayList) stores FieldPosition instances with\r
-        // NumberFormat.Field.  Because NumberFormat.Field is not serializable, we need\r
-        // to clear the contents of the list when writeObject is called.  We could remove\r
-        // the field or make it transient, but it will break serialization compatibility.\r
-        attributes.clear();\r
-\r
-        stream.defaultWriteObject();\r
-    }\r
-//#endif\r
-\r
-    /**\r
-     * First, read the default serializable fields from the stream.  Then\r
-     * if <code>serialVersionOnStream</code> is less than 1, indicating that\r
-     * the stream was written by JDK 1.1, initialize <code>useExponentialNotation</code>\r
-     * to false, since it was 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
-        /*Bug 4185761 validate fields\r
-          [Richard/GCL]\r
-        */\r
-        // We only need to check the maximum counts because NumberFormat\r
-        // .readObject has already ensured that the maximum is greater than the\r
-        // minimum count.\r
-        /*Commented for compatibility with previous version, and reserved for further use\r
-        if (getMaximumIntegerDigits() > DOUBLE_INTEGER_DIGITS ||\r
-            getMaximumFractionDigits() > DOUBLE_FRACTION_DIGITS) {\r
-            throw new InvalidObjectException("Digit count out of range");\r
-        }*/\r
-        /* Truncate the maximumIntegerDigits to DOUBLE_INTEGER_DIGITS and maximumFractionDigits\r
-         * to DOUBLE_FRACTION_DIGITS\r
-         */\r
-        if (getMaximumIntegerDigits() > DOUBLE_INTEGER_DIGITS) {\r
-             setMaximumIntegerDigits(DOUBLE_INTEGER_DIGITS);\r
-        }\r
-        if (getMaximumFractionDigits() > DOUBLE_FRACTION_DIGITS) {\r
-            setMaximumFractionDigits(DOUBLE_FRACTION_DIGITS);\r
-        }\r
-        if (serialVersionOnStream < 2) {\r
-            exponentSignAlwaysShown = false;\r
-            setInternalRoundingIncrement(null);\r
-            setRoundingDouble();\r
-            roundingMode = BigDecimal.ROUND_HALF_EVEN;\r
-            formatWidth = 0;\r
-            pad = ' ';\r
-            padPosition = PAD_BEFORE_PREFIX;\r
-            if (serialVersionOnStream < 1) {\r
-                // Didn't have exponential fields\r
-                useExponentialNotation = false;\r
-            }\r
-        }\r
-        if (serialVersionOnStream < 3) {\r
-            // Versions prior to 3 do not store a currency object.\r
-            // Create one to match the DecimalFormatSymbols object.\r
-            setCurrencyForSymbols();\r
-        }\r
-        serialVersionOnStream = currentSerialVersion;\r
-        digitList = new DigitList();\r
-\r
-//#if defined(FOUNDATION10)\r
-//#else\r
-        if (roundingIncrement != null) {\r
-            setInternalRoundingIncrement(new BigDecimal(roundingIncrement));\r
-            setRoundingDouble();\r
-        }   \r
-//#endif\r
-    }\r
-\r
-\r
-    private void setInternalRoundingIncrement(BigDecimal value) {\r
-        roundingIncrementICU = value;\r
-//#if defined(FOUNDATION10)\r
-//#else\r
-        roundingIncrement = value == null ? null : value.toBigDecimal();\r
-//#endif\r
-    }\r
-\r
-    //----------------------------------------------------------------------\r
-    // INSTANCE VARIABLES\r
-    //----------------------------------------------------------------------\r
-\r
-    private transient DigitList digitList = new DigitList();\r
-\r
-    /**\r
-     * The symbol used as a prefix when formatting positive numbers, e.g. "+".\r
-     *\r
-     * @serial\r
-     * @see #getPositivePrefix\r
-     */\r
-    private String  positivePrefix = "";\r
-\r
-    /**\r
-     * The symbol used as a suffix when formatting positive numbers.\r
-     * This is often an empty string.\r
-     *\r
-     * @serial\r
-     * @see #getPositiveSuffix\r
-     */\r
-    private String  positiveSuffix = "";\r
-\r
-    /**\r
-     * The symbol used as a prefix when formatting negative numbers, e.g. "-".\r
-     *\r
-     * @serial\r
-     * @see #getNegativePrefix\r
-     */\r
-    private String  negativePrefix = "-";\r
-\r
-    /**\r
-     * The symbol used as a suffix when formatting negative numbers.\r
-     * This is often an empty string.\r
-     *\r
-     * @serial\r
-     * @see #getNegativeSuffix\r
-     */\r
-    private String  negativeSuffix = "";\r
-    \r
-    /**\r
-     * The prefix pattern for non-negative numbers.  This variable corresponds\r
-     * to <code>positivePrefix</code>.\r
-     *\r
-     * <p>This pattern is expanded by the method <code>expandAffix()</code> to\r
-     * <code>positivePrefix</code> to update the latter to reflect changes in\r
-     * <code>symbols</code>.  If this variable is <code>null</code> then\r
-     * <code>positivePrefix</code> is taken as a literal value that does not\r
-     * change when <code>symbols</code> changes.  This variable is always\r
-     * <code>null</code> for <code>DecimalFormat</code> objects older than\r
-     * stream version 2 restored from stream.\r
-     *\r
-     * @serial\r
-     */\r
-    //[Richard/GCL]\r
-    private String posPrefixPattern;\r
-\r
-    /**\r
-     * The suffix pattern for non-negative numbers.  This variable corresponds\r
-     * to <code>positiveSuffix</code>.  This variable is analogous to\r
-     * <code>posPrefixPattern</code>; see that variable for further\r
-     * documentation.\r
-     *\r
-     * @serial\r
-     */\r
-    //[Richard/GCL]\r
-    private String posSuffixPattern;\r
-\r
-    /**\r
-     * The prefix pattern for negative numbers.  This variable corresponds\r
-     * to <code>negativePrefix</code>.  This variable is analogous to\r
-     * <code>posPrefixPattern</code>; see that variable for further\r
-     * documentation.\r
-     *\r
-     * @serial\r
-     */\r
-    //[Richard/GCL]\r
-    private String negPrefixPattern;\r
-\r
-    /**\r
-     * The suffix pattern for negative numbers.  This variable corresponds\r
-     * to <code>negativeSuffix</code>.  This variable is analogous to\r
-     * <code>posPrefixPattern</code>; see that variable for further\r
-     * documentation.\r
-     *\r
-     * @serial\r
-     */\r
-    //[Richard/GCL]\r
-    private String negSuffixPattern;\r
-\r
-\r
-\r
-    /**\r
-     * Formatter for ChoiceFormat-based currency names.  If this field\r
-     * is not null, then delegate to it to format currency symbols.\r
-     * @since ICU 2.6\r
-     */\r
-    private ChoiceFormat currencyChoice;\r
-\r
-    /**\r
-     * The multiplier for use in percent, permill, etc.\r
-     *\r
-     * @serial\r
-     * @see #getMultiplier\r
-     */\r
-    private int     multiplier = 1;\r
-    \r
-    /**\r
-     * The number of digits between grouping separators in the integer\r
-     * portion of a number.  Must be greater than 0 if\r
-     * <code>NumberFormat.groupingUsed</code> is true.\r
-     *\r
-     * @serial\r
-     * @see #getGroupingSize\r
-     * @see NumberFormat#isGroupingUsed\r
-     */\r
-    private byte    groupingSize = 3;  // invariant, > 0 if useThousands\r
-\r
-    // [NEW]\r
-    /**\r
-     * The secondary grouping size.  This is only used for Hindi\r
-     * numerals, which use a primary grouping of 3 and a secondary\r
-     * grouping of 2, e.g., "12,34,567".  If this value is less than\r
-     * 1, then secondary grouping is equal to the primary grouping.\r
-     * \r
-     */\r
-    private byte    groupingSize2 = 0;\r
-    \r
-    /**\r
-     * If true, forces the decimal separator to always appear in a formatted\r
-     * number, even if the fractional part of the number is zero.\r
-     *\r
-     * @serial\r
-     * @see #isDecimalSeparatorAlwaysShown\r
-     */\r
-    private boolean decimalSeparatorAlwaysShown = false;\r
-    \r
-    \r
-    /**\r
-     * The <code>DecimalFormatSymbols</code> object used by this format.\r
-     * It contains the symbols used to format numbers, e.g. the grouping separator,\r
-     * decimal separator, and so on.\r
-     *\r
-     * @serial\r
-     * @see #setDecimalFormatSymbols\r
-     * @see DecimalFormatSymbols\r
-     */\r
-    private DecimalFormatSymbols symbols = null; // LIU new DecimalFormatSymbols();\r
-\r
-    /**\r
-     * True to use significant digits rather than integer and fraction\r
-     * digit counts.\r
-     * @serial\r
-     * @since ICU 3.0\r
-     */\r
-    private boolean useSignificantDigits = false;\r
-\r
-    /**\r
-     * The minimum number of significant digits to show.  Must be >= 1\r
-     * and <= maxSignificantDigits.  Ignored unless\r
-     * useSignificantDigits == true.\r
-     * @serial\r
-     * @since ICU 3.0\r
-     */\r
-    private int minSignificantDigits = 1;\r
-\r
-    /**\r
-     * The maximum number of significant digits to show.  Must be >=\r
-     * minSignficantDigits.  Ignored unless useSignificantDigits ==\r
-     * true.\r
-     * @serial\r
-     * @since ICU 3.0\r
-     */\r
-    private int maxSignificantDigits = 6;\r
-\r
-    /**\r
-     * True to force the use of exponential (i.e. scientific) notation when formatting\r
-     * numbers.\r
-     * <p>\r
-     * Note that the JDK 1.2 public API provides no way to set this field,\r
-     * even though it is supported by the implementation and the stream format.\r
-     * The intent is that this will be added to the API in the future.\r
-     *\r
-     * @serial\r
-     */\r
-    private boolean useExponentialNotation;  // Newly persistent in JDK 1.2\r
-\r
-    /**\r
-     * The minimum number of digits used to display the exponent when a number is\r
-     * formatted in exponential notation.  This field is ignored if\r
-     * <code>useExponentialNotation</code> is not true.\r
-     * <p>\r
-     * Note that the JDK 1.2 public API provides no way to set this field,\r
-     * even though it is supported by the implementation and the stream format.\r
-     * The intent is that this will be added to the API in the future.\r
-     *\r
-     * @serial\r
-     */\r
-    private byte    minExponentDigits;       // Newly persistent in JDK 1.2\r
-\r
-    // [NEW]\r
-    /**\r
-     * If true, the exponent is always prefixed with either the plus\r
-     * sign or the minus sign.  Otherwise, only negative exponents are\r
-     * prefixed with the minus sign.  This has no effect unless\r
-     * <code>useExponentialNotation</code> is true.\r
-     * @serial\r
-     * @since AlphaWorks NumberFormat\r
-     */\r
-    private boolean exponentSignAlwaysShown = false;\r
-\r
-//#if defined(FOUNDATION10)\r
-//#else\r
-    // [NEW]\r
-    /**\r
-     * The value to which numbers are rounded during formatting.  For example,\r
-     * if the rounding increment is 0.05, then 13.371 would be formatted as\r
-     * 13.350, assuming 3 fraction digits.  Has the value <code>null</code> if\r
-     * rounding is not in effect, or a positive value if rounding is in effect.\r
-     * Default value <code>null</code>.\r
-     * @serial\r
-     * @since AlphaWorks NumberFormat\r
-     */\r
-    // Note: this is kept in sync with roundingIncrementICU.\r
-    // it is only kept around to avoid a conversion when formatting a java.math.BigDecimal\r
-    private java.math.BigDecimal roundingIncrement = null;\r
-//#endif\r
-\r
-    // [NEW]\r
-    /**\r
-     * The value to which numbers are rounded during formatting.  For example,\r
-     * if the rounding increment is 0.05, then 13.371 would be formatted as\r
-     * 13.350, assuming 3 fraction digits.  Has the value <code>null</code> if\r
-     * rounding is not in effect, or a positive value if rounding is in effect.\r
-     * Default value <code>null</code>.\r
-     * WARNING: the roundingIncrement value is the one serialized.\r
-     * @serial\r
-     * @since AlphaWorks NumberFormat\r
-     */\r
-    private transient BigDecimal roundingIncrementICU = null;\r
-\r
-    // [NEW]\r
-    /**\r
-     * The rounding increment as a double.  If this value is <= 0, then no\r
-     * rounding is done.  This value is\r
-     * <code>roundingIncrementICU.doubleValue()</code>.  Default value 0.0.\r
-     */\r
-    private transient double roundingDouble = 0.0;\r
-\r
-    // [NEW]\r
-    /**\r
-     * If the roundingDouble is the reciprocal of an integer (the most common case!),\r
-     * this is set to be that integer. Otherwise it is 0.0.\r
-     */\r
-    private transient double roundingDoubleReciprocal = 0.0;\r
-\r
-    // [NEW]\r
-    /**\r
-     * The rounding mode.  This value controls any rounding operations which\r
-     * occur when applying a rounding increment or when reducing the number of\r
-     * fraction digits to satisfy a maximum fraction digits limit.  The value\r
-     * may assume any of the <code>BigDecimal</code> rounding mode values.\r
-     * Default value <code>BigDecimal.ROUND_HALF_EVEN</code>.\r
-     * @serial\r
-     * @since AlphaWorks NumberFormat\r
-     */\r
-    private int roundingMode = BigDecimal.ROUND_HALF_EVEN;\r
-\r
-    // [NEW]\r
-    /**\r
-     * Operations on <code>BigDecimal</code> numbers are controlled by a\r
-     * {@link MathContext} object, which provides the context (precision and\r
-     * other information) for the operation. The default <code>MathContext</code> \r
-     * settings are <code>digits=0, form=PLAIN, lostDigits=false, \r
-     * roundingMode=ROUND_HALF_UP</code>; these settings perform fixed point \r
-     * arithmetic with unlimited precision, as defined for the original BigDecimal \r
-     * class in Java 1.1 and Java 1.2\r
-     */\r
-    private MathContext mathContext = new MathContext(0, MathContext.PLAIN); // context for plain unlimited math\r
-\r
-    // [NEW]\r
-    /**\r
-     * The padded format width, or zero if there is no padding.  Must\r
-     * be >= 0.  Default value zero.\r
-     * @serial\r
-     * @since AlphaWorks NumberFormat\r
-     */\r
-    private int formatWidth = 0;\r
-\r
-    // [NEW]\r
-    /**\r
-     * The character used to pad the result of format to\r
-     * <code>formatWidth</code>, if padding is in effect.  Default value ' '.\r
-     * @serial\r
-     * @since AlphaWorks NumberFormat\r
-     */\r
-    private char pad = ' ';\r
-\r
-    // [NEW]\r
-    /**\r
-     * The position in the string at which the <code>pad</code> character\r
-     * will be inserted, if padding is in effect.  Must have a value from\r
-     * <code>PAD_BEFORE_PREFIX</code> to <code>PAD_AFTER_SUFFIX</code>.\r
-     * Default value <code>PAD_BEFORE_PREFIX</code>.\r
-     * @serial\r
-     * @since AlphaWorks NumberFormat\r
-     */\r
-    private int padPosition = PAD_BEFORE_PREFIX;\r
-\r
-    /**\r
-     * True if {@link #parse(String, ParsePosition)} to return BigDecimal\r
-     * rather than Long, Double or BigDecimal except special values.\r
-     * This property is introduced for J2SE 5 compatibility support.\r
-     * @serial\r
-     * @since ICU 3.6\r
-     * @see #setParseBigDecimal(boolean)\r
-     * @see #isParseBigDecimal()\r
-     */\r
-    private boolean parseBigDecimal = false;\r
-\r
-    //----------------------------------------------------------------------\r
-\r
-    static final int currentSerialVersion = 3;\r
-\r
-    /**\r
-     * The internal serial version which says which version was written\r
-     * Possible values are:\r
-     * <ul>\r
-     * <li><b>0</b> (default): versions before JDK 1.2\r
-     * <li><b>1</b>: version from JDK 1.2 and later, which includes the two new fields\r
-     *      <code>useExponentialNotation</code> and <code>minExponentDigits</code>.\r
-     * <li><b>2</b>: version on AlphaWorks, which adds roundingMode, formatWidth,\r
-     *      pad, padPosition, exponentSignAlwaysShown, roundingIncrement.\r
-     * <li><b>3</b>: ICU 2.2.  Adds currency object.\r
-     * </ul>\r
-     * @serial */\r
-    private int serialVersionOnStream = currentSerialVersion;\r
-\r
-    //----------------------------------------------------------------------\r
-    // CONSTANTS\r
-    //----------------------------------------------------------------------\r
-\r
-    // [NEW]\r
-    /**\r
-     * Constant for <code>getPadPosition()</code> and\r
-     * <code>setPadPosition()</code> specifying pad characters inserted before\r
-     * the prefix.\r
-     * @see #setPadPosition\r
-     * @see #getPadPosition\r
-     * @see #PAD_AFTER_PREFIX\r
-     * @see #PAD_BEFORE_SUFFIX\r
-     * @see #PAD_AFTER_SUFFIX\r
-     * @stable ICU 2.0\r
-     */\r
-    public static final int PAD_BEFORE_PREFIX = 0;\r
-\r
-    // [NEW]\r
-    /**\r
-     * Constant for <code>getPadPosition()</code> and\r
-     * <code>setPadPosition()</code> specifying pad characters inserted after\r
-     * the prefix.\r
-     * @see #setPadPosition\r
-     * @see #getPadPosition\r
-     * @see #PAD_BEFORE_PREFIX\r
-     * @see #PAD_BEFORE_SUFFIX\r
-     * @see #PAD_AFTER_SUFFIX\r
-     * @stable ICU 2.0\r
-     */\r
-    public static final int PAD_AFTER_PREFIX  = 1;\r
-\r
-    // [NEW]\r
-    /**\r
-     * Constant for <code>getPadPosition()</code> and\r
-     * <code>setPadPosition()</code> specifying pad characters inserted before\r
-     * the suffix.\r
-     * @see #setPadPosition\r
-     * @see #getPadPosition\r
-     * @see #PAD_BEFORE_PREFIX\r
-     * @see #PAD_AFTER_PREFIX\r
-     * @see #PAD_AFTER_SUFFIX\r
-     * @stable ICU 2.0\r
-     */\r
-    public static final int PAD_BEFORE_SUFFIX = 2;\r
-\r
-    // [NEW]\r
-    /**\r
-     * Constant for <code>getPadPosition()</code> and\r
-     * <code>setPadPosition()</code> specifying pad characters inserted after\r
-     * the suffix.\r
-     * @see #setPadPosition\r
-     * @see #getPadPosition\r
-     * @see #PAD_BEFORE_PREFIX\r
-     * @see #PAD_AFTER_PREFIX\r
-     * @see #PAD_BEFORE_SUFFIX\r
-     * @stable ICU 2.0\r
-     */\r
-    public static final int PAD_AFTER_SUFFIX  = 3;\r
-\r
-    // Constants for characters used in programmatic (unlocalized) patterns.\r
-    private static final char       PATTERN_ZERO_DIGIT         = '0';\r
-    private static final char       PATTERN_GROUPING_SEPARATOR = ',';\r
-    private static final char       PATTERN_DECIMAL_SEPARATOR  = '.';\r
-    private static final char       PATTERN_DIGIT              = '#';\r
-            static final char       PATTERN_SIGNIFICANT_DIGIT  = '@';\r
-            static final char       PATTERN_EXPONENT           = 'E'; // [NEW]\r
-            static final char       PATTERN_PLUS_SIGN          = '+'; // [NEW]\r
-\r
-    // Affix\r
-    private static final char       PATTERN_PER_MILLE          = '\u2030';\r
-    private static final char       PATTERN_PERCENT            = '%';\r
-            static final char       PATTERN_PAD_ESCAPE         = '*'; // [NEW]\r
-    /*Bug 4212072\r
-      To meet the need of expandAffix(String, StirngBuffer)\r
-      [Richard/GCL]\r
-    */\r
-    private static final char       PATTERN_MINUS              = '-'; //[Richard/GCL]\r
-\r
-    // Other    \r
-    private static final char       PATTERN_SEPARATOR          = ';';\r
-\r
-    // Pad escape is package private to allow access by DecimalFormatSymbols.\r
-    // Also plus sign.  Also exponent.\r
-\r
-    /**\r
-     * The CURRENCY_SIGN is the standard Unicode symbol for currency.  It\r
-     * is used in patterns and substitued with either the currency symbol,\r
-     * or if it is doubled, with the international currency symbol.  If the\r
-     * CURRENCY_SIGN is seen in a pattern, then the decimal separator is\r
-     * replaced with the monetary decimal separator.\r
-     *\r
-     * The CURRENCY_SIGN is not localized.\r
-     */\r
-    private static final char       CURRENCY_SIGN = '\u00A4';\r
-\r
-    private static final char       QUOTE = '\'';\r
-    \r
-    /* Upper limit on integer and fraction digits for a Java double\r
-       [Richard/GCL]\r
-    */\r
-    static final int DOUBLE_INTEGER_DIGITS  = 309;\r
-    static final int DOUBLE_FRACTION_DIGITS = 340;\r
-\r
-    /**\r
-     * When someone turns on scientific mode, we assume that more than this\r
-     * number of digits is due to flipping from some other mode that didn't\r
-     * restrict the maximum, and so we force 1 integer digit.  We don't bother\r
-     * to track and see if someone is using exponential notation with more than\r
-     * this number, it wouldn't make sense anyway, and this is just to make sure\r
-     * that someone turning on scientific mode with default settings doesn't\r
-     * end up with lots of zeroes.\r
-     */\r
-    static final int MAX_SCIENTIFIC_INTEGER_DIGITS = 8;\r
-\r
-//#if defined(FOUNDATION10)\r
-//##    // we're not compatible with other versions, since we have no java.math.BigDecimal field\r
-//##    private static final long serialVersionUID = 2;\r
-//#else\r
-    // Proclaim JDK 1.1 serial compatibility.\r
-    private static final long serialVersionUID = 864413376551465018L;\r
-//#endif\r
-\r
-//#if defined(FOUNDATION10) || defined(J2SE13)\r
-//#else\r
-    private ArrayList attributes = new ArrayList();\r
-//#endif\r
-\r
-    /*\r
-     * Following are used in currency format\r
-     */\r
-/*\r
-    // triple currency sign char array\r
-    private static final char[] tripleCurrencySign = {0xA4, 0xA4, 0xA4};\r
-    // triple currency sign string\r
-    private static final String tripleCurrencyStr = new String(tripleCurrencySign);\r
-\r
-    // default currency plural pattern char array\r
-    private static final char[] defaultCurrencyPluralPatternChar = {0, '.', '#', '#', ' ', 0xA4, 0xA4, 0xA4};\r
-    // default currency plural pattern string\r
-    private static final String defaultCurrencyPluralPattern = new String(defaultCurrencyPluralPatternChar);\r
-*/\r
-\r
-    // pattern used in this formatter\r
-    private String formatPattern = "";\r
-    // style is only valid when decimal formatter is constructed by\r
-    // DecimalFormat(pattern, decimalFormatSymbol, style)\r
-    private int style = NumberFormat.NUMBERSTYLE;\r
-    /*\r
-     * Represents whether this is a currency format, and which\r
-     * currency format style.\r
-     * 0: not currency format type;\r
-     * 1: currency style -- symbol name, such as "$" for US dollar.\r
-     * 2: currency style -- ISO name, such as USD for US dollar.\r
-     * 3: currency style -- plural long name, such as "US Dollar" for\r
-     *                      "1.00 US Dollar", or "US Dollars" for\r
-     *                      "3.00 US Dollars".\r
-     */\r
-    private int currencySignCount = 0;\r
-\r
-\r
-    /* For parsing purose,\r
-     * Need to remember all prefix patterns and suffix patterns of \r
-     * every currency format pattern, \r
-     * including the pattern of default currecny style, ISO currency style,\r
-     * and plural currency style. And the patterns are set through applyPattern.\r
-     * Following are used to represent the affix patterns in currency plural\r
-     * formats.\r
-     */\r
-    private static final class AffixForCurrency {\r
-        // negative prefix pattern\r
-        private String negPrefixPatternForCurrency = null; \r
-        // negative suffix pattern\r
-        private String negSuffixPatternForCurrency = null; \r
-        // positive prefix pattern\r
-        private String posPrefixPatternForCurrency = null; \r
-        // positive suffix pattern\r
-        private String posSuffixPatternForCurrency = null; \r
-        private int patternType;\r
-        \r
-        public AffixForCurrency() { \r
-            patternType = Currency.SYMBOL_NAME; \r
-        }\r
-\r
-        public AffixForCurrency(String negPrefix, String negSuffix,\r
-                                String posPrefix, String posSuffix,\r
-                                int type) {\r
-            negPrefixPatternForCurrency = negPrefix;\r
-            negSuffixPatternForCurrency = negSuffix;\r
-            posPrefixPatternForCurrency = posPrefix;\r
-            posSuffixPatternForCurrency = posSuffix;\r
-            patternType = type;\r
-        }\r
-\r
-        public String getNegPrefix() {\r
-            return negPrefixPatternForCurrency;\r
-        }\r
-\r
-        public String getNegSuffix() {\r
-            return negSuffixPatternForCurrency;\r
-        }\r
-\r
-        public String getPosPrefix() {\r
-            return posPrefixPatternForCurrency;\r
-        }\r
-\r
-        public String getPosSuffix() {\r
-            return posSuffixPatternForCurrency;\r
-        }\r
-\r
-        public int getPatternType() {\r
-            return patternType;\r
-        }\r
-    }\r
-    // Affix patter set for currency.\r
-    // It is a set of AffixForCurrency,\r
-    // each element of the set saves the negative prefix,\r
-    // negative suffix, positive prefix, and positive suffix of a pattern.\r
-    private transient Set affixPatternsForCurrency = null;\r
-\r
-    // For currency parsing, since currency parsing need to parse\r
-    // against all currency patterns, before the parsing, need to set up \r
-    // the affix patterns for currency.\r
-    private transient boolean isReadyForParsing = false;\r
-\r
-    // Information needed for DecimalFormat to format/parse currency plural.\r
-    private CurrencyPluralInfo currencyPluralInfo = null;\r
-\r
-}\r
-\r
-//eof\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.ObjectInputStream;
+import java.math.BigInteger;
+import java.text.ChoiceFormat;
+import java.text.FieldPosition;
+import java.text.ParsePosition;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+//#if defined(FOUNDATION10)
+//#else
+import java.io.ObjectOutputStream;
+//#endif
+
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+import java.text.AttributedCharacterIterator;
+import java.text.AttributedString;
+import java.text.Format;
+import java.util.ArrayList;
+//#endif
+
+import com.ibm.icu.impl.UCharacterProperty;
+import com.ibm.icu.impl.Utility;
+import com.ibm.icu.lang.UCharacter;
+import com.ibm.icu.math.BigDecimal;
+import com.ibm.icu.util.Currency;
+import com.ibm.icu.util.CurrencyAmount;
+import com.ibm.icu.util.ULocale;
+import com.ibm.icu.math.MathContext;
+
+//This is an enhanced version of DecimalFormat that is based on the standard version in the JDK. 
+/**
+ * <code>DecimalFormat</code> is a concrete subclass of
+ * {@link NumberFormat} that formats decimal numbers. It has a variety of
+ * features designed to make it possible to parse and format numbers in any
+ * locale, including support for Western, Arabic, or Indic digits.  It also
+ * supports different flavors of numbers, including integers ("123"),
+ * fixed-point numbers ("123.4"), scientific notation ("1.23E4"), percentages
+ * ("12%"), and currency amounts ("$123.00", "USD123.00", "123.00 US dollars").
+ * All of these flavors can be easily localized.
+ *
+ * 
+ * <p>To obtain a {@link NumberFormat} for a specific locale (including the
+ * default locale) call one of <code>NumberFormat</code>'s factory methods such
+ * as {@link NumberFormat#getInstance}. Do not call the <code>DecimalFormat</code>
+ * constructors directly, unless you know what you are doing, since the
+ * {@link NumberFormat} factory methods may return subclasses other than
+ * <code>DecimalFormat</code>. If you need to customize the format object, do
+ * something like this:
+ *
+ * <blockquote><pre>
+ * NumberFormat f = NumberFormat.getInstance(loc);
+ * if (f instanceof DecimalFormat) {
+ *     ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true);
+ * }</pre></blockquote>
+ *
+ * <p><strong>Example Usage</strong>
+ *
+ * <blockquote><pre>
+ * <strong>// Print out a number using the localized number, currency,
+ * // and percent format for each locale</strong>
+ * Locale[] locales = NumberFormat.getAvailableLocales();
+ * double myNumber = -1234.56;
+ * NumberFormat format;
+ * for (int j=0; j<3; ++j) {
+ *     System.out.println("FORMAT");
+ *     for (int i = 0; i < locales.length; ++i) {
+ *         if (locales[i].getCountry().length() == 0) {
+ *            // Skip language-only locales
+ *            continue;
+ *         }
+ *         System.out.print(locales[i].getDisplayName());
+ *         switch (j) {
+ *         case 0:
+ *             format = NumberFormat.getInstance(locales[i]); break;
+ *         case 1:
+ *             format = NumberFormat.getCurrencyInstance(locales[i]); break;
+ *         default:
+ *             format = NumberFormat.getPercentInstance(locales[i]); break;
+ *         }
+ *         try {
+ *             // Assume format is a DecimalFormat
+ *             System.out.print(": " + ((DecimalFormat) format).toPattern()
+ *                              + " -> " + form.format(myNumber));
+ *         } catch (Exception e) {}
+ *         try {
+ *             System.out.println(" -> " + format.parse(form.format(myNumber)));
+ *         } catch (ParseException e) {}
+ *     }
+ * }</pre></blockquote>
+ *
+ * <P>
+ * Another example use getInstance(style)
+ * <P>
+ * <pre>
+ * <strong>// Print out a number using the localized number, currency,
+ * // percent, scientific, integer, iso currency, and plural currency
+ * // format for each locale</strong>
+ * ULocale locale = new ULocale("en_US");
+ * double myNumber = 1234.56;
+ * for (int j=NumberFormat.NUMBERSTYLE; j<=NumberFormat.PLURALCURRENCYSTYLE; ++j) {
+ *     NumberFormat format = NumberFormat.getInstance(locale, j);
+ *     try {
+ *         // Assume format is a DecimalFormat
+ *         System.out.print(": " + ((DecimalFormat) format).toPattern()
+ *                          + " -> " + form.format(myNumber));
+ *     } catch (Exception e) {}
+ *     try {
+ *         System.out.println(" -> " + format.parse(form.format(myNumber)));
+ *     } catch (ParseException e) {}
+ * }</pre></blockquote>
+ *
+ * <h4>Patterns</h4>
+ *
+ * <p>A <code>DecimalFormat</code> consists of a <em>pattern</em> and a set of
+ * <em>symbols</em>.  The pattern may be set directly using
+ * {@link #applyPattern}, or indirectly using other API methods which
+ * manipulate aspects of the pattern, such as the minimum number of integer
+ * digits.  The symbols are stored in a {@link DecimalFormatSymbols}
+ * object.  When using the {@link NumberFormat} factory methods, the
+ * pattern and symbols are read from ICU's locale data.
+ * 
+ * <h4>Special Pattern Characters</h4>
+ *
+ * <p>Many characters in a pattern are taken literally; they are matched during
+ * parsing and output unchanged during formatting.  Special characters, on the
+ * other hand, stand for other characters, strings, or classes of characters.
+ * For example, the '#' character is replaced by a localized digit.  Often the
+ * replacement character is the same as the pattern character; in the U.S. locale,
+ * the ',' grouping character is replaced by ','.  However, the replacement is
+ * still happening, and if the symbols are modified, the grouping character
+ * changes.  Some special characters affect the behavior of the formatter by
+ * their presence; for example, if the percent character is seen, then the
+ * value is multiplied by 100 before being displayed.
+ *
+ * <p>To insert a special character in a pattern as a literal, that is, without
+ * any special meaning, the character must be quoted.  There are some exceptions to
+ * this which are noted below.
+ *
+ * <p>The characters listed here are used in non-localized patterns.  Localized
+ * patterns use the corresponding characters taken from this formatter's
+ * {@link DecimalFormatSymbols} object instead, and these characters lose
+ * their special status.  Two exceptions are the currency sign and quote, which
+ * are not localized.
+ *
+ * <blockquote>
+ * <table border=0 cellspacing=3 cellpadding=0 summary="Chart showing symbol,
+ *  location, localized, and meaning.">
+ *   <tr bgcolor="#ccccff">
+ *     <th align=left>Symbol
+ *     <th align=left>Location
+ *     <th align=left>Localized?
+ *     <th align=left>Meaning
+ *   <tr valign=top>
+ *     <td><code>0</code>
+ *     <td>Number
+ *     <td>Yes
+ *     <td>Digit
+ *   <tr valign=top bgcolor="#eeeeff">
+ *     <td><code>1-9</code>
+ *     <td>Number
+ *     <td>Yes
+ *     <td>'1' through '9' indicate rounding. 
+ *         
+ *   <tr valign=top>
+ *     <td><code>@</code>
+ *     <td>Number
+ *     <td>No
+ *     <td>Significant digit
+ *   <tr valign=top bgcolor="#eeeeff">
+ *     <td><code>#</code>
+ *     <td>Number
+ *     <td>Yes
+ *     <td>Digit, zero shows as absent
+ *   <tr valign=top>
+ *     <td><code>.</code>
+ *     <td>Number
+ *     <td>Yes
+ *     <td>Decimal separator or monetary decimal separator
+ *   <tr valign=top bgcolor="#eeeeff">
+ *     <td><code>-</code>
+ *     <td>Number
+ *     <td>Yes
+ *     <td>Minus sign
+ *   <tr valign=top>
+ *     <td><code>,</code>
+ *     <td>Number
+ *     <td>Yes
+ *     <td>Grouping separator
+ *   <tr valign=top bgcolor="#eeeeff">
+ *     <td><code>E</code>
+ *     <td>Number
+ *     <td>Yes
+ *     <td>Separates mantissa and exponent in scientific notation.
+ *         <em>Need not be quoted in prefix or suffix.</em>
+ *   <tr valign=top>
+ *     <td><code>+</code>
+ *     <td>Exponent
+ *     <td>Yes
+ *     <td>Prefix positive exponents with localized plus sign.
+ *         <em>Need not be quoted in prefix or suffix.</em>
+ *   <tr valign=top bgcolor="#eeeeff">
+ *     <td><code>;</code>
+ *     <td>Subpattern boundary
+ *     <td>Yes
+ *     <td>Separates positive and negative subpatterns
+ *   <tr valign=top>
+ *     <td><code>%</code>
+ *     <td>Prefix or suffix
+ *     <td>Yes
+ *     <td>Multiply by 100 and show as percentage
+ *   <tr valign=top bgcolor="#eeeeff">
+ *     <td><code>&#92;u2030</code>
+ *     <td>Prefix or suffix
+ *     <td>Yes
+ *     <td>Multiply by 1000 and show as per mille
+ *   <tr valign=top>
+ *     <td><code>&#164;</code> (<code>&#92;u00A4</code>)
+ *     <td>Prefix or suffix
+ *     <td>No
+ *     <td>Currency sign, replaced by currency symbol.  If
+ *         doubled, replaced by international currency symbol.
+ *         If tripled, replaced by currency plural names, for example,
+ *         "US dollar" or "US dollars" for America.
+ *         If present in a pattern, the monetary decimal separator
+ *         is used instead of the decimal separator.
+ *   <tr valign=top bgcolor="#eeeeff">
+ *     <td><code>'</code>
+ *     <td>Prefix or suffix
+ *     <td>No
+ *     <td>Used to quote special characters in a prefix or suffix,
+ *         for example, <code>"'#'#"</code> formats 123 to
+ *         <code>"#123"</code>.  To create a single quote
+ *         itself, use two in a row: <code>"# o''clock"</code>.
+ *   <tr valign=top>
+ *     <td><code>*</code>
+ *     <td>Prefix or suffix boundary
+ *     <td>Yes
+ *     <td>Pad escape, precedes pad character
+ * </table>
+ * </blockquote>
+ *
+ * <p>A <code>DecimalFormat</code> pattern contains a postive and negative
+ * subpattern, for example, "#,##0.00;(#,##0.00)".  Each subpattern has a
+ * prefix, a numeric part, and a suffix.  If there is no explicit negative
+ * subpattern, the negative subpattern is the localized minus sign prefixed to the
+ * positive subpattern. That is, "0.00" alone is equivalent to "0.00;-0.00".  If there
+ * is an explicit negative subpattern, it serves only to specify the negative
+ * prefix and suffix; the number of digits, minimal digits, and other
+ * characteristics are ignored in the negative subpattern. That means that
+ * "#,##0.0#;(#)" has precisely the same result as "#,##0.0#;(#,##0.0#)".
+ *
+ * <p>The prefixes, suffixes, and various symbols used for infinity, digits,
+ * thousands separators, decimal separators, etc. may be set to arbitrary
+ * values, and they will appear properly during formatting.  However, care must
+ * be taken that the symbols and strings do not conflict, or parsing will be
+ * unreliable.  For example, either the positive and negative prefixes or the
+ * suffixes must be distinct for {@link #parse} to be able
+ * to distinguish positive from negative values.  Another example is that the
+ * decimal separator and thousands separator should be distinct characters, or
+ * parsing will be impossible.
+ *
+ * <p>The <em>grouping separator</em> is a character that separates clusters of
+ * integer digits to make large numbers more legible.  It commonly used for
+ * thousands, but in some locales it separates ten-thousands.  The <em>grouping
+ * size</em> is the number of digits between the grouping separators, such as 3
+ * for "100,000,000" or 4 for "1 0000 0000". There are actually two different
+ * grouping sizes: One used for the least significant integer digits, the
+ * <em>primary grouping size</em>, and one used for all others, the
+ * <em>secondary grouping size</em>.  In most locales these are the same, but
+ * sometimes they are different. For example, if the primary grouping interval
+ * is 3, and the secondary is 2, then this corresponds to the pattern
+ * "#,##,##0", and the number 123456789 is formatted as "12,34,56,789".  If a
+ * pattern contains multiple grouping separators, the interval between the last
+ * one and the end of the integer defines the primary grouping size, and the
+ * interval between the last two defines the secondary grouping size. All others
+ * are ignored, so "#,##,###,####" == "###,###,####" == "##,#,###,####".
+ *
+ * <p>Illegal patterns, such as "#.#.#" or "#.###,###", will cause
+ * <code>DecimalFormat</code> to throw an {@link IllegalArgumentException}
+ * with a message that describes the problem.
+ *
+ * <h4>Pattern BNF</h4>
+ *
+ * <pre>
+ * pattern    := subpattern (';' subpattern)?
+ * subpattern := prefix? number exponent? suffix?
+ * number     := (integer ('.' fraction)?) | sigDigits
+ * prefix     := '&#92;u0000'..'&#92;uFFFD' - specialCharacters
+ * suffix     := '&#92;u0000'..'&#92;uFFFD' - specialCharacters
+ * integer    := '#'* '0'* '0'
+ * fraction   := '0'* '#'*
+ * sigDigits  := '#'* '@' '@'* '#'*
+ * exponent   := 'E' '+'? '0'* '0'
+ * padSpec    := '*' padChar
+ * padChar    := '&#92;u0000'..'&#92;uFFFD' - quote
+ * &#32;
+ * Notation:
+ *   X*       0 or more instances of X
+ *   X?       0 or 1 instances of X
+ *   X|Y      either X or Y
+ *   C..D     any character from C up to D, inclusive
+ *   S-T      characters in S, except those in T
+ * </pre>
+ * The first subpattern is for positive numbers. The second (optional)
+ * subpattern is for negative numbers.
+ * 
+ * <p>Not indicated in the BNF syntax above:
+ *
+ * <ul><li>The grouping separator ',' can occur inside the integer and
+ * sigDigits elements, between any two pattern characters of that
+ * element, as long as the integer or sigDigits element is not
+ * followed by the exponent element.
+ *
+ * <li>Two grouping intervals are recognized: That between the
+ *     decimal point and the first grouping symbol, and that
+ *     between the first and second grouping symbols. These
+ *     intervals are identical in most locales, but in some
+ *     locales they differ. For example, the pattern
+ *     &quot;#,##,###&quot; formats the number 123456789 as
+ *     &quot;12,34,56,789&quot;.</li>
+ * 
+ * <li>
+ * The pad specifier <code>padSpec</code> may appear before the prefix,
+ * after the prefix, before the suffix, after the suffix, or not at all.
+ *
+ * <li>
+ * In place of '0', the digits '1' through '9' may be used to
+ * indicate a rounding increment.
+ * </ul>
+ *
+ * <h4>Parsing</h4>
+ *
+ * <p><code>DecimalFormat</code> parses all Unicode characters that represent
+ * decimal digits, as defined by {@link UCharacter#digit}.  In addition,
+ * <code>DecimalFormat</code> also recognizes as digits the ten consecutive
+ * characters starting with the localized zero digit defined in the
+ * {@link DecimalFormatSymbols} object.  During formatting, the
+ * {@link DecimalFormatSymbols}-based digits are output.
+ *
+ * <p>During parsing, grouping separators are ignored.
+ *
+ * <p>For currency parsing, the formatter is able to parse every currency
+ * style formats no matter which style the formatter is constructed with.
+ * For example, a formatter instance gotten from 
+ * NumberFormat.getInstance(ULocale, NumberFormat.CURRENCYSTYLE) can parse
+ * formats such as "USD1.00" and "3.00 US dollars".
+ *
+ * <p>If {@link #parse(String, ParsePosition)} fails to parse
+ * a string, it returns <code>null</code> and leaves the parse position
+ * unchanged.  The convenience method {@link #parse(String)}
+ * indicates parse failure by throwing a {@link java.text.ParseException}.
+ *
+ * <h4>Formatting</h4>
+ *
+ * <p>Formatting is guided by several parameters, all of which can be
+ * specified either using a pattern or using the API.  The following
+ * description applies to formats that do not use <a href="#sci">scientific
+ * notation</a> or <a href="#sigdig">significant digits</a>.
+ *
+ * <ul><li>If the number of actual integer digits exceeds the
+ * <em>maximum integer digits</em>, then only the least significant
+ * digits are shown.  For example, 1997 is formatted as "97" if the
+ * maximum integer digits is set to 2.
+ *
+ * <li>If the number of actual integer digits is less than the
+ * <em>minimum integer digits</em>, then leading zeros are added.  For
+ * example, 1997 is formatted as "01997" if the minimum integer digits
+ * is set to 5.
+ *
+ * <li>If the number of actual fraction digits exceeds the <em>maximum
+ * fraction digits</em>, then half-even rounding it performed to the
+ * maximum fraction digits.  For example, 0.125 is formatted as "0.12"
+ * if the maximum fraction digits is 2.  This behavior can be changed
+ * by specifying a rounding increment and a rounding mode.
+ *
+ * <li>If the number of actual fraction digits is less than the
+ * <em>minimum fraction digits</em>, then trailing zeros are added.
+ * For example, 0.125 is formatted as "0.1250" if the mimimum fraction
+ * digits is set to 4.
+ *
+ * <li>Trailing fractional zeros are not displayed if they occur
+ * <em>j</em> positions after the decimal, where <em>j</em> is less
+ * than the maximum fraction digits. For example, 0.10004 is
+ * formatted as "0.1" if the maximum fraction digits is four or less.
+ * </ul>
+ * 
+ * <p><strong>Special Values</strong>
+ *
+ * <p><code>NaN</code> is represented as a single character, typically
+ * <code>&#92;uFFFD</code>.  This character is determined by the
+ * {@link DecimalFormatSymbols} object.  This is the only value for which
+ * the prefixes and suffixes are not used.
+ *
+ * <p>Infinity is represented as a single character, typically
+ * <code>&#92;u221E</code>, with the positive or negative prefixes and suffixes
+ * applied.  The infinity character is determined by the
+ * {@link DecimalFormatSymbols} object.
+ *
+ * <a name="sci"><h4>Scientific Notation</h4></a>
+ *
+ * <p>Numbers in scientific notation are expressed as the product of a mantissa
+ * and a power of ten, for example, 1234 can be expressed as 1.234 x 10<sup>3</sup>. The
+ * mantissa is typically in the half-open interval [1.0, 10.0) or sometimes [0.0, 1.0),
+ * but it need not be.  <code>DecimalFormat</code> supports arbitrary mantissas.
+ * <code>DecimalFormat</code> can be instructed to use scientific
+ * notation through the API or through the pattern.  In a pattern, the exponent
+ * character immediately followed by one or more digit characters indicates
+ * scientific notation.  Example: "0.###E0" formats the number 1234 as
+ * "1.234E3".
+ *
+ * <ul>
+ * <li>The number of digit characters after the exponent character gives the
+ * minimum exponent digit count.  There is no maximum.  Negative exponents are
+ * formatted using the localized minus sign, <em>not</em> the prefix and suffix
+ * from the pattern.  This allows patterns such as "0.###E0 m/s".  To prefix
+ * positive exponents with a localized plus sign, specify '+' between the
+ * exponent and the digits: "0.###E+0" will produce formats "1E+1", "1E+0",
+ * "1E-1", etc.  (In localized patterns, use the localized plus sign rather than
+ * '+'.)
+ *
+ * <li>The minimum number of integer digits is achieved by adjusting the
+ * exponent.  Example: 0.00123 formatted with "00.###E0" yields "12.3E-4".  This
+ * only happens if there is no maximum number of integer digits.  If there is a
+ * maximum, then the minimum number of integer digits is fixed at one.
+ *
+ * <li>The maximum number of integer digits, if present, specifies the exponent
+ * grouping.  The most common use of this is to generate <em>engineering
+ * notation</em>, in which the exponent is a multiple of three, e.g.,
+ * "##0.###E0".  The number 12345 is formatted using "##0.####E0" as "12.345E3".
+ *
+ * <li>When using scientific notation, the formatter controls the
+ * digit counts using significant digits logic.  The maximum number of
+ * significant digits limits the total number of integer and fraction
+ * digits that will be shown in the mantissa; it does not affect
+ * parsing.  For example, 12345 formatted with "##0.##E0" is "12.3E3".
+ * See the section on significant digits for more details.
+ *
+ * <li>The number of significant digits shown is determined as
+ * follows: If areSignificantDigitsUsed() returns false, then the
+ * minimum number of significant digits shown is one, and the maximum
+ * number of significant digits shown is the sum of the <em>minimum
+ * integer</em> and <em>maximum fraction</em> digits, and is
+ * unaffected by the maximum integer digits.  If this sum is zero,
+ * then all significant digits are shown.  If
+ * areSignificantDigitsUsed() returns true, then the significant digit
+ * counts are specified by getMinimumSignificantDigits() and
+ * getMaximumSignificantDigits().  In this case, the number of
+ * integer digits is fixed at one, and there is no exponent grouping.
+ *
+ * <li>Exponential patterns may not contain grouping separators.
+ * </ul>
+ *
+ * <a name="sigdig"><h4>
+ * Significant Digits</h4></a>
+ *
+ * <code>DecimalFormat</code> has two ways of controlling how many
+ * digits are shows: (a) significant digits counts, or (b) integer and
+ * fraction digit counts.  Integer and fraction digit counts are
+ * described above.  When a formatter is using significant digits
+ * counts, the number of integer and fraction digits is not specified
+ * directly, and the formatter settings for these counts are ignored.
+ * Instead, the formatter uses however many integer and fraction
+ * digits are required to display the specified number of significant
+ * digits.  Examples:
+ *
+ * <blockquote>
+ * <table border=0 cellspacing=3 cellpadding=0>
+ *   <tr bgcolor="#ccccff">
+ *     <th align=left>Pattern
+ *     <th align=left>Minimum significant digits
+ *     <th align=left>Maximum significant digits
+ *     <th align=left>Number
+ *     <th align=left>Output of format()
+ *   <tr valign=top>
+ *     <td><code>@@@</code>
+ *     <td>3
+ *     <td>3
+ *     <td>12345
+ *     <td><code>12300</code>
+ *   <tr valign=top bgcolor="#eeeeff">
+ *     <td><code>@@@</code>
+ *     <td>3
+ *     <td>3
+ *     <td>0.12345
+ *     <td><code>0.123</code>
+ *   <tr valign=top>
+ *     <td><code>@@##</code>
+ *     <td>2
+ *     <td>4
+ *     <td>3.14159
+ *     <td><code>3.142</code>
+ *   <tr valign=top bgcolor="#eeeeff">
+ *     <td><code>@@##</code>
+ *     <td>2
+ *     <td>4
+ *     <td>1.23004
+ *     <td><code>1.23</code>
+ * </table>
+ * </blockquote>
+ *
+ * <ul>
+ * <li>Significant digit counts may be expressed using patterns that
+ * specify a minimum and maximum number of significant digits.  These
+ * are indicated by the <code>'@'</code> and <code>'#'</code>
+ * characters.  The minimum number of significant digits is the number
+ * of <code>'@'</code> characters.  The maximum number of significant
+ * digits is the number of <code>'@'</code> characters plus the number
+ * of <code>'#'</code> characters following on the right.  For
+ * example, the pattern <code>"@@@"</code> indicates exactly 3
+ * significant digits.  The pattern <code>"@##"</code> indicates from
+ * 1 to 3 significant digits.  Trailing zero digits to the right of
+ * the decimal separator are suppressed after the minimum number of
+ * significant digits have been shown.  For example, the pattern
+ * <code>"@##"</code> formats the number 0.1203 as
+ * <code>"0.12"</code>.
+ *
+ * <li>If a pattern uses significant digits, it may not contain a
+ * decimal separator, nor the <code>'0'</code> pattern character.
+ * Patterns such as <code>"@00"</code> or <code>"@.###"</code> are
+ * disallowed.
+ *
+ * <li>Any number of <code>'#'</code> characters may be prepended to
+ * the left of the leftmost <code>'@'</code> character.  These have no
+ * effect on the minimum and maximum significant digits counts, but
+ * may be used to position grouping separators.  For example,
+ * <code>"#,#@#"</code> indicates a minimum of one significant digits,
+ * a maximum of two significant digits, and a grouping size of three.
+ *
+ * <li>In order to enable significant digits formatting, use a pattern
+ * containing the <code>'@'</code> pattern character.  Alternatively,
+ * call {@link #setSignificantDigitsUsed setSignificantDigitsUsed(true)}.
+ *
+ * <li>In order to disable significant digits formatting, use a
+ * pattern that does not contain the <code>'@'</code> pattern
+ * character. Alternatively, call {@link #setSignificantDigitsUsed
+ * setSignificantDigitsUsed(false)}.
+ *
+ * <li>The number of significant digits has no effect on parsing.
+ *
+ * <li>Significant digits may be used together with exponential notation. Such
+ * patterns are equivalent to a normal exponential pattern with a minimum and
+ * maximum integer digit count of one, a minimum fraction digit count of
+ * <code>getMinimumSignificantDigits() - 1</code>, and a maximum fraction digit
+ * count of <code>getMaximumSignificantDigits() - 1</code>. For example, the
+ * pattern <code>"@@###E0"</code> is equivalent to <code>"0.0###E0"</code>.
+ *
+ * <li>If signficant digits are in use, then the integer and fraction
+ * digit counts, as set via the API, are ignored.  If significant
+ * digits are not in use, then the signficant digit counts, as set via
+ * the API, are ignored.
+ *
+ * </ul>
+ * 
+ * <h4>
+ * Padding</h4>
+ *
+ * <p><code>DecimalFormat</code> supports padding the result of
+ * {@link #format} to a specific width.  Padding may be specified either
+ * through the API or through the pattern syntax.  In a pattern the pad escape
+ * character, followed by a single pad character, causes padding to be parsed
+ * and formatted.  The pad escape character is '*' in unlocalized patterns, and
+ * can be localized using {@link DecimalFormatSymbols#setPadEscape}.  For
+ * example, <code>"$*x#,##0.00"</code> formats 123 to <code>"$xx123.00"</code>,
+ * and 1234 to <code>"$1,234.00"</code>.
+ *
+ * <ul>
+ * <li>When padding is in effect, the width of the positive subpattern,
+ * including prefix and suffix, determines the format width.  For example, in
+ * the pattern <code>"* #0 o''clock"</code>, the format width is 10.
+ *
+ * <li>The width is counted in 16-bit code units (Java <code>char</code>s).
+ *
+ * <li>Some parameters which usually do not matter have meaning when padding is
+ * used, because the pattern width is significant with padding.  In the pattern
+ * "* ##,##,#,##0.##", the format width is 14.  The initial characters "##,##,"
+ * do not affect the grouping size or maximum integer digits, but they do affect
+ * the format width.
+ *
+ * <li>Padding may be inserted at one of four locations: before the prefix,
+ * after the prefix, before the suffix, or after the suffix.  If padding is
+ * specified in any other location, {@link #applyPattern} throws an {@link
+ * IllegalArgumentException}.  If there is no prefix, before the
+ * prefix and after the prefix are equivalent, likewise for the suffix.
+ *
+ * <li>When specified in a pattern, the 16-bit <code>char</code> immediately
+ * following the pad escape is the pad character. This may be any character,
+ * including a special pattern character. That is, the pad escape
+ * <em>escapes</em> the following character. If there is no character after
+ * the pad escape, then the pattern is illegal.
+ *
+ * </ul>
+ *
+ * <p>
+ * <strong>Rounding</strong>
+ *
+ * <p><code>DecimalFormat</code> supports rounding to a specific increment.  For
+ * example, 1230 rounded to the nearest 50 is 1250.  1.234 rounded to the
+ * nearest 0.65 is 1.3.  The rounding increment may be specified through the API
+ * or in a pattern.  To specify a rounding increment in a pattern, include the
+ * increment in the pattern itself.  "#,#50" specifies a rounding increment of
+ * 50.  "#,##0.05" specifies a rounding increment of 0.05.
+ *
+ * <ul>
+ * <li>Rounding only affects the string produced by formatting.  It does
+ * not affect parsing or change any numerical values.
+ *
+ * <li>A <em>rounding mode</em> determines how values are rounded; see the
+ * {@link com.ibm.icu.math.BigDecimal} documentation for a description of the
+ * modes.  Rounding increments specified in patterns use the default mode,
+ * {@link com.ibm.icu.math.BigDecimal#ROUND_HALF_EVEN}.
+ *
+ * <li>Some locales use rounding in their currency formats to reflect the
+ * smallest currency denomination.
+ *
+ * <li>In a pattern, digits '1' through '9' specify rounding, but otherwise
+ * behave identically to digit '0'.
+ * </ul>
+ *
+ * <h4>Synchronization</h4>
+ *
+ * <p><code>DecimalFormat</code> objects are not synchronized.  Multiple
+ * threads should not access one formatter concurrently.
+ *
+ * @see          java.text.Format
+ * @see          NumberFormat
+ * @author       Mark Davis
+ * @author       Alan Liu
+ * @stable ICU 2.0
+ */
+public class DecimalFormat extends NumberFormat {
+
+    /**
+     * Create a DecimalFormat using the default pattern and symbols
+     * for the default locale. This is a convenient way to obtain a
+     * DecimalFormat when internationalization is not the main concern.
+     * <p>
+     * To obtain standard formats for a given locale, use the factory methods
+     * on NumberFormat such as getNumberInstance. These factories will
+     * return the most appropriate sub-class of NumberFormat for a given
+     * locale.
+     * @see NumberFormat#getInstance
+     * @see NumberFormat#getNumberInstance
+     * @see NumberFormat#getCurrencyInstance
+     * @see NumberFormat#getPercentInstance
+     * @stable ICU 2.0
+     */
+    public DecimalFormat() {
+        // [NEW]
+        ULocale def = ULocale.getDefault();
+        String pattern = getPattern(def, 0);
+        // Always applyPattern after the symbols are set
+        this.symbols = new DecimalFormatSymbols(def);
+        setCurrency(Currency.getInstance(def));
+        applyPatternWithoutExpandAffix(pattern, false);
+        if (currencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT) {
+            currencyPluralInfo = new CurrencyPluralInfo(def);
+            // the exact pattern is not known until the plural count is known.
+            // so, no need to expand affix now.
+        } else {
+            expandAffixAdjustWidth(null);
+        }
+    }
+
+
+    /**
+     * Create a DecimalFormat from the given pattern and the symbols
+     * for the default locale. This is a convenient way to obtain a
+     * DecimalFormat when internationalization is not the main concern.
+     * <p>
+     * To obtain standard formats for a given locale, use the factory methods
+     * on NumberFormat such as getNumberInstance. These factories will
+     * return the most appropriate sub-class of NumberFormat for a given
+     * locale.
+     * @param pattern A non-localized pattern string.
+     * @exception IllegalArgumentException if the given pattern is invalid.
+     * @see NumberFormat#getInstance
+     * @see NumberFormat#getNumberInstance
+     * @see NumberFormat#getCurrencyInstance
+     * @see NumberFormat#getPercentInstance
+     * @stable ICU 2.0
+     */
+    public DecimalFormat(String pattern) {
+        // Always applyPattern after the symbols are set
+        ULocale def = ULocale.getDefault();
+        this.symbols = new DecimalFormatSymbols(def);
+        setCurrency(Currency.getInstance(def));
+        applyPatternWithoutExpandAffix( pattern, false );
+        if (currencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT) {
+            currencyPluralInfo = new CurrencyPluralInfo(def);
+        } else {
+            expandAffixAdjustWidth(null);
+        }
+    }
+
+
+    /**
+     * Create a DecimalFormat from the given pattern and symbols.
+     * Use this constructor when you need to completely customize the
+     * behavior of the format.
+     * <p>
+     * To obtain standard formats for a given
+     * locale, use the factory methods on NumberFormat such as
+     * getInstance or getCurrencyInstance. If you need only minor adjustments
+     * to a standard format, you can modify the format returned by
+     * a NumberFormat factory method.
+     * @param pattern a non-localized pattern string
+     * @param symbols the set of symbols to be used
+     * @exception IllegalArgumentException if the given pattern is invalid
+     * @see NumberFormat#getInstance
+     * @see NumberFormat#getNumberInstance
+     * @see NumberFormat#getCurrencyInstance
+     * @see NumberFormat#getPercentInstance
+     * @see DecimalFormatSymbols
+     * @stable ICU 2.0
+     */
+    public DecimalFormat(String pattern, DecimalFormatSymbols symbols) {
+        createFromPatternAndSymbols(pattern, symbols);
+    }
+
+    private void createFromPatternAndSymbols(String pattern, DecimalFormatSymbols inputSymbols) {
+        // Always applyPattern after the symbols are set
+        symbols = (DecimalFormatSymbols) inputSymbols.clone();
+        setCurrencyForSymbols();
+        applyPatternWithoutExpandAffix(pattern, false);
+        if (currencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT) {
+            currencyPluralInfo = new CurrencyPluralInfo(symbols.getLocale());
+        } else {
+            expandAffixAdjustWidth(null);
+        }
+    }
+
+
+    /**
+     * Create a DecimalFormat from the given pattern, symbols,
+     * information used for currency plural format, and format style.
+     * Use this constructor when you need to completely customize the
+     * behavior of the format.
+     * <p>
+     * To obtain standard formats for a given
+     * locale, use the factory methods on NumberFormat such as
+     * getInstance or getCurrencyInstance. 
+     * <p>
+     * If you need only minor adjustments to a standard format, 
+     * you can modify the format returned by
+     * a NumberFormat factory method using the setters.
+     * <p>
+     * If you want to completely customize a decimal format,
+     * using your own DecimalFormatSymbols (such as group separators) and
+     * your own information for currency plural formatting (such as
+     * plural rule and currency plural patterns), you can use this constructor.
+     * <p> 
+     * @param pattern a non-localized pattern string
+     * @param symbols the set of symbols to be used
+     * @param infoInput the information used for currency plural format, 
+     *                  including currency plural patterns and plural rules.
+     * @param style the decimal formatting style, 
+     *              it is one of the following values:
+     *              NumberFormat.NUMBERSTYLE;
+     *              NumberFormat.CURRENCYSTYLE;
+     *              NumberFormat.PERCENTSTYLE;
+     *              NumberFormat.SCIENTIFICSTYLE;
+     *              NumberFormat.INTEGERSTYLE;
+     *              NumberFormat.ISOCURRENCYSTYLE;
+     *              NumberFormat.PLURALCURRENCYSTYLE;
+     * @draft ICU 4.2
+     * @provisional This API might change or be removed in a future release.
+     */
+    public DecimalFormat(String pattern, DecimalFormatSymbols symbols,
+                         CurrencyPluralInfo infoInput,
+                         int style) {
+        CurrencyPluralInfo info = infoInput;
+        if (style == NumberFormat.PLURALCURRENCYSTYLE) {
+            info = (CurrencyPluralInfo)infoInput.clone();
+        }
+        create(pattern, symbols, info, style);
+    }
+
+
+    private void create(String pattern, DecimalFormatSymbols inputSymbols,
+                        CurrencyPluralInfo info,
+                        int inputStyle) {
+        if (inputStyle != NumberFormat.PLURALCURRENCYSTYLE) {
+            createFromPatternAndSymbols(pattern, inputSymbols);
+        } else {
+            // Always applyPattern after the symbols are set
+            symbols = (DecimalFormatSymbols) inputSymbols.clone();
+            currencyPluralInfo = info;
+            // the pattern used in format is not fixed until formatting,
+            // in which, the number is known and 
+            // will be used to pick the right pattern based on plural count.
+            // Here, set the pattern as the pattern of plural count == "other".
+            // For most locale, the patterns are probably the same for all
+            // plural count. If not, the right pattern need to be re-applied
+            // during format.
+            String currencyPluralPatternForOther = currencyPluralInfo.getCurrencyPluralPattern("other");
+            applyPatternWithoutExpandAffix(currencyPluralPatternForOther,false);
+            setCurrencyForSymbols();
+        }
+        style = inputStyle;
+    }
+
+
+    /*
+     * Create a DecimalFormat for currency plural format 
+     * from the given pattern, symbols, and style.
+     */
+    DecimalFormat(String pattern, DecimalFormatSymbols inputSymbols, int style) {
+        CurrencyPluralInfo info = null;
+        if (style == NumberFormat.PLURALCURRENCYSTYLE) {
+            info = new CurrencyPluralInfo(inputSymbols.getLocale());
+        }
+        create(pattern, inputSymbols, info, style);
+    }
+
+    /**
+     * @stable ICU 2.0
+     */
+    public StringBuffer format(double number, StringBuffer result,
+            FieldPosition fieldPosition) {
+        return format(number, result, fieldPosition, false);
+    }
+    
+    // [Spark/CDL] The actual method to format number. If boolean value
+    // parseAttr == true, then attribute information will be recorded.
+    private StringBuffer format(double number, StringBuffer result,
+            FieldPosition fieldPosition, boolean parseAttr) 
+    {
+        fieldPosition.setBeginIndex(0);
+        fieldPosition.setEndIndex(0);
+
+        if (Double.isNaN(number))
+        {
+            if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD) {
+                fieldPosition.setBeginIndex(result.length());
+            }
+//#if defined(FOUNDATION10) || defined(J2SE13) 
+//#else 
+            else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {
+                fieldPosition.setBeginIndex(result.length());
+            }
+//#endif 
+
+            result.append(symbols.getNaN());
+            // [Spark/CDL] Add attribute for NaN here.
+            // result.append(symbols.getNaN());
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+            if (parseAttr) {
+                addAttribute(Field.INTEGER, result.length()
+                        - symbols.getNaN().length(), result.length());
+            }
+//#endif
+            if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD) {
+                fieldPosition.setEndIndex(result.length());
+            }
+//#if defined(FOUNDATION10) || defined(J2SE13) 
+//#else 
+            else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {
+                fieldPosition.setEndIndex(result.length());
+            }
+//#endif 
+
+            addPadding(result, fieldPosition, 0, 0);
+            return result;
+        }
+
+        // Do this BEFORE checking to see if value is infinite or negative!
+        if (multiplier != 1) number *= multiplier;
+
+        /* Detecting whether a double is negative is easy with the exception of
+         * the value -0.0.  This is a double which has a zero mantissa (and
+         * exponent), but a negative sign bit.  It is semantically distinct from
+         * a zero with a positive sign bit, and this distinction is important
+         * to certain kinds of computations.  However, it's a little tricky to
+         * detect, since (-0.0 == 0.0) and !(-0.0 < 0.0).  How then, you may
+         * ask, does it behave distinctly from +0.0?  Well, 1/(-0.0) ==
+         * -Infinity.  Proper detection of -0.0 is needed to deal with the
+         * issues raised by bugs 4106658, 4106667, and 4147706.  Liu 7/6/98.
+         */
+        boolean isNegative = (number < 0.0) || (number == 0.0 && 1/number < 0.0);
+        if (isNegative) number = -number;
+
+        // Apply rounding after multiplier
+        if (roundingDouble > 0.0) {
+            // number = roundingDouble
+            //  * round(number / roundingDouble, roundingMode, isNegative);
+            double newNumber = round(number, roundingDouble, roundingDoubleReciprocal, roundingMode, isNegative);
+            if (newNumber == 0.0 && number != newNumber) isNegative = false; // if we touched it, then make zero be zero.
+            number = newNumber;
+        }
+
+        if (Double.isInfinite(number))
+        {
+            int prefixLen = appendAffix(result, isNegative, true, parseAttr);
+
+            if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD) {
+                fieldPosition.setBeginIndex(result.length());
+            }
+//#if defined(FOUNDATION10) || defined(J2SE13) 
+//#else 
+            else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {
+                fieldPosition.setBeginIndex(result.length());
+            }
+//#endif 
+
+            // [Spark/CDL] Add attribute for infinity here.
+            result.append(symbols.getInfinity());
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+            if (parseAttr) {
+                addAttribute(Field.INTEGER, result.length()
+                        - symbols.getInfinity().length(), result.length());
+            }
+//#endif
+            if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD) {
+                fieldPosition.setEndIndex(result.length());
+            }
+//#if defined(FOUNDATION10) || defined(J2SE13) 
+//#else 
+            else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {
+                fieldPosition.setEndIndex(result.length());
+            }
+//#endif 
+
+            int suffixLen = appendAffix(result, isNegative, false, parseAttr);
+
+            addPadding(result, fieldPosition, prefixLen, suffixLen);
+            return result;
+        }
+
+        // At this point we are guaranteed a nonnegative finite
+        // number.
+        synchronized(digitList) {
+            digitList.set(number, precision(false),
+                          !useExponentialNotation && !areSignificantDigitsUsed());
+            return subformat(number, result, fieldPosition, isNegative, false,
+                    parseAttr);
+        }
+    }
+    
+    // [NEW]
+    /**
+     * Round a double value to the nearest multiple of the given
+     * rounding increment, according to the given mode.  This is
+     * equivalent to rounding value/roundingInc to the nearest
+     * integer, according to the given mode, and returning that
+     * integer * roundingInc.
+     * Note this is changed from the version in 2.4, since division of doubles
+     * have inaccuracies. jitterbug 1871.
+     * @param number the absolute value of the number to be rounded
+     * @param roundingInc the rounding increment
+     * @param roundingIncReciprocal if non-zero, is the 
+     * @param mode a BigDecimal rounding mode
+     * @param isNegative true if the number to be rounded is negative
+     * @return the absolute value of the rounded result
+     */
+    private static double round(double number, double roundingInc, 
+            double roundingIncReciprocal, int mode, boolean isNegative) {
+        
+        double div = roundingIncReciprocal == 0.0 
+            ? number / roundingInc
+            : number * roundingIncReciprocal;
+        
+        // do the absolute cases first
+        
+        switch (mode) {
+        case BigDecimal.ROUND_CEILING:
+            div = (isNegative ? Math.floor(div + epsilon) : Math.ceil(div - epsilon));
+            break;
+        case BigDecimal.ROUND_FLOOR:
+            div = (isNegative ? Math.ceil(div - epsilon) : Math.floor(div + epsilon));
+            break;
+        case BigDecimal.ROUND_DOWN:
+            div = (Math.floor(div + epsilon));
+            break;
+        case BigDecimal.ROUND_UP:
+            div = (Math.ceil(div - epsilon));
+            break;
+        case BigDecimal.ROUND_UNNECESSARY:
+            if (div != Math.floor(div)) {
+                throw new ArithmeticException("Rounding necessary");
+            }
+            return number;
+        default:
+            
+            // Handle complex cases, where the choice depends on the closer value.
+            
+            // We figure out the distances to the two possible values, ceiling and floor.
+            // We then go for the diff that is smaller.
+            // Only if they are equal does the mode matter.
+
+            double ceil = Math.ceil(div);
+            double ceildiff = ceil - div; // (ceil * roundingInc) - number;
+            double floor = Math.floor(div);
+            double floordiff = div - floor; // number - (floor * roundingInc);
+            
+            // Note that the diff values were those mapped back to the "normal" space
+            // by using the roundingInc. I don't have access to the original author of the code
+            // but suspect that that was to produce better result in edge cases because of machine
+            // precision, rather than simply using the difference between, say, ceil and div.
+            // However, it didn't work in all cases. Am trying instead using an epsilon value.
+            
+            switch (mode) {
+            case BigDecimal.ROUND_HALF_EVEN:
+                // We should be able to just return Math.rint(a), but this
+                // doesn't work in some VMs.
+                // if one is smaller than the other, take the corresponding side
+                if (floordiff + epsilon < ceildiff) {
+                        div = floor;
+                    } else if (ceildiff + epsilon < floordiff) {
+                        div = ceil;
+                } else { // they are equal, so we want to round to whichever is even
+                    double testFloor = floor / 2;
+                    div = (testFloor == Math.floor(testFloor)) ? floor : ceil;
+                }
+                break;
+            case BigDecimal.ROUND_HALF_DOWN:
+                div = ((floordiff <= ceildiff + epsilon) ? floor : ceil);
+                break;
+            case BigDecimal.ROUND_HALF_UP:
+                div = ((ceildiff <= floordiff + epsilon) ? ceil : floor);
+                break;
+            default:
+                throw new IllegalArgumentException("Invalid rounding mode: " + mode);
+            }
+        }
+        number = roundingIncReciprocal == 0.0
+            ? div * roundingInc
+            : div / roundingIncReciprocal;
+        return number;
+    }
+    private static double epsilon = 0.00000000001;
+
+    /**
+     * @stable ICU 2.0
+     */
+    // [Spark/CDL] Delegate to format_long_StringBuffer_FieldPosition_boolean
+    public StringBuffer format(long number, StringBuffer result,
+            FieldPosition fieldPosition) {
+        return format(number, result, fieldPosition, false);
+    }
+
+    private StringBuffer format(long number, StringBuffer result,
+            FieldPosition fieldPosition, boolean parseAttr) 
+    {
+        fieldPosition.setBeginIndex(0);
+        fieldPosition.setEndIndex(0);
+
+        // If we are to do rounding, we need to move into the BigDecimal
+        // domain in order to do divide/multiply correctly.
+        // [NEW]
+        if (roundingIncrementICU != null) {
+            return format(BigDecimal.valueOf(number), result, fieldPosition);
+        }
+
+        boolean isNegative = (number < 0);
+        if (isNegative) number = -number;
+
+        // In general, long values always represent real finite numbers, so
+        // we don't have to check for +/- Infinity or NaN.  However, there
+        // is one case we have to be careful of:  The multiplier can push
+        // a number near MIN_VALUE or MAX_VALUE outside the legal range.  We
+        // check for this before multiplying, and if it happens we use BigInteger
+        // instead.
+        // [NEW]
+        if (multiplier != 1) {
+            boolean tooBig = false;
+            if (number < 0) { // This can only happen if number == Long.MIN_VALUE
+                long cutoff = Long.MIN_VALUE / multiplier;
+                tooBig = (number <= cutoff); // number == cutoff can only happen if multiplier == -1
+            } else {
+                long cutoff = Long.MAX_VALUE / multiplier;
+                tooBig = (number > cutoff);
+            }
+            if (tooBig) {
+                // [Spark/CDL] Use
+                // format_BigInteger_StringBuffer_FieldPosition_boolean instead
+                // parseAttr is used to judge whether to synthesize attributes.
+                return format(
+                        BigInteger.valueOf(isNegative ? -number : number),
+                        result, fieldPosition, parseAttr);
+            }
+        }
+
+        number *= multiplier;
+        synchronized(digitList) {
+            digitList.set(number, precision(true));
+            return subformat(number, result, fieldPosition, isNegative, true, parseAttr);
+        }
+    }
+
+    // [NEW]
+    /**
+     * Format a BigInteger number.
+     * 
+     * @stable ICU 2.0
+     */
+    public StringBuffer format(BigInteger number, StringBuffer result,
+            FieldPosition fieldPosition) {
+        return format(number, result, fieldPosition, false);
+    }
+
+    // [Spark/CDL] 
+    private StringBuffer format(BigInteger number, StringBuffer result,
+            FieldPosition fieldPosition, boolean parseAttr) {
+        // If we are to do rounding, we need to move into the BigDecimal
+        // domain in order to do divide/multiply correctly.
+        if (roundingIncrementICU != null) {
+            return format(new BigDecimal(number), result, fieldPosition);
+        }
+
+        if (multiplier != 1) {
+            number = number.multiply(BigInteger.valueOf(multiplier));
+        }
+
+        // At this point we are guaranteed a nonnegative finite
+        // number.
+        synchronized(digitList) {
+            digitList.set(number, precision(true));
+            return subformat(number.intValue(), result, fieldPosition, number.signum() < 0, true, parseAttr);
+        }
+    }
+
+//#if defined(FOUNDATION10)
+//#else
+    // [NEW]
+    /**
+     * Format a BigDecimal number.
+     * @stable ICU 2.0
+     */
+    public StringBuffer format(java.math.BigDecimal number, StringBuffer result,
+                               FieldPosition fieldPosition) {
+        return format(number, result, fieldPosition, false);
+    }
+    
+    private StringBuffer format(java.math.BigDecimal number,
+            StringBuffer result, FieldPosition fieldPosition, boolean parseAttr) {
+        if (multiplier != 1) {
+            number = number.multiply(java.math.BigDecimal.valueOf(multiplier));
+        }
+
+        if (roundingIncrement != null) {
+            number = number.divide(roundingIncrement, 0, roundingMode)
+                    .multiply(roundingIncrement);
+        }
+
+        synchronized(digitList) {
+            digitList.set(number, precision(false),
+                          !useExponentialNotation && !areSignificantDigitsUsed());
+            return subformat(number.doubleValue(), result, fieldPosition, number.signum() < 0, false, parseAttr);
+        }        
+    }
+//#endif
+    
+    // [NEW]
+    /**
+     * Format a BigDecimal number.
+     * @stable ICU 2.0
+     */
+    public StringBuffer format(BigDecimal number, StringBuffer result,
+                               FieldPosition fieldPosition) {
+        /* This method is just a copy of the corresponding java.math.BigDecimal
+         * method for now.  It isn't very efficient since it must create a
+         * conversion object to do math on the rounding increment.  In the
+         * future we may try to clean this up, or even better, limit our support
+         * to just one flavor of BigDecimal.
+         */
+        if (multiplier != 1) {
+            number = number.multiply(BigDecimal.valueOf(multiplier), mathContext);
+        }
+
+        if (roundingIncrementICU != null) {
+            number = number.divide(roundingIncrementICU, 0, roundingMode)
+                .multiply(roundingIncrementICU, mathContext);
+        }
+
+        synchronized(digitList) {
+            digitList.set(number, precision(false),
+                          !useExponentialNotation && !areSignificantDigitsUsed());
+            return subformat(number.doubleValue(), result, fieldPosition, number.signum() < 0, false, false);
+        }        
+    }
+
+    /**
+     * Return true if a grouping separator belongs at the given
+     * position, based on whether grouping is in use and the values of
+     * the primary and secondary grouping interval.
+     * @param pos the number of integer digits to the right of
+     * the current position.  Zero indicates the position after the
+     * rightmost integer digit.
+     * @return true if a grouping character belongs at the current
+     * position.
+     */
+    private boolean isGroupingPosition(int pos) {
+        boolean result = false;
+        if (isGroupingUsed() && (pos > 0) && (groupingSize > 0)) {
+            if ((groupingSize2 > 0) && (pos > groupingSize)) {
+                result = ((pos - groupingSize) % groupingSize2) == 0;
+            } else {
+                result = pos % groupingSize == 0;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Return the number of fraction digits to display, or the total
+     * number of digits for significant digit formats and exponential
+     * formats.
+     */
+    private int precision(boolean isIntegral) {
+        if (areSignificantDigitsUsed()) {
+            return getMaximumSignificantDigits();
+        } else if (useExponentialNotation) {
+            return getMinimumIntegerDigits() + getMaximumFractionDigits();
+        } else {
+            return isIntegral ? 0 : getMaximumFractionDigits();
+        }
+    }
+
+    private StringBuffer subformat(int number, StringBuffer result, 
+                                   FieldPosition fieldPosition,
+                                   boolean isNegative, boolean isInteger, 
+                                   boolean parseAttr) {
+        if (currencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT) { 
+            return subformat(currencyPluralInfo.select(number), result, fieldPosition,
+                             isNegative, isInteger, parseAttr);
+        } else {
+            return subformat(result, fieldPosition, isNegative, isInteger, parseAttr);
+        }
+    }
+
+    private StringBuffer subformat(double number, StringBuffer result, 
+                                   FieldPosition fieldPosition,
+                                   boolean isNegative, boolean isInteger,
+                                   boolean parseAttr) {
+        if (currencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT) { 
+            return subformat(currencyPluralInfo.select(number), result, fieldPosition,
+                             isNegative, isInteger, parseAttr);
+        } else {
+            return subformat(result, fieldPosition, isNegative, isInteger, parseAttr);
+        }
+    }
+
+    private StringBuffer subformat(String pluralCount, 
+            StringBuffer result,
+            FieldPosition fieldPosition, boolean isNegative, boolean isInteger,
+            boolean parseAttr) 
+    {
+        // There are 2 ways to activate currency plural format:
+        // by applying a pattern with 3 currency sign directly,
+        // or by instantiate a decimal formatter using PLURALCURRENCYSTYLE.
+        // For both cases, the number of currency sign in the pattern is 3.
+        // Even if the number of currency sign in the pattern is 3, 
+        // it does not mean we need to reset the pattern.
+        // For 1st case, we do not need to reset pattern.
+        // For 2nd case, we might need to reset pattern,
+        // if the default pattern (corresponding to plural count 'other')
+        // we use is different from the pattern based on 'pluralCount'.
+        // 
+        // style is only valid when decimal formatter is constructed through
+        // DecimalFormat(pattern, symbol, style)
+        if (style == NumberFormat.PLURALCURRENCYSTYLE) {
+            // May need to reset pattern if the style is PLURALCURRENCYSTYLE.
+            String currencyPluralPattern = currencyPluralInfo.getCurrencyPluralPattern(pluralCount);
+            if (formatPattern.equals(currencyPluralPattern) == false) {
+                applyPatternWithoutExpandAffix(currencyPluralPattern, false);
+            }
+        }
+        // Expand the affix to the right name according to
+        // the plural rule.
+        // This is only used for currency plural formatting.
+        // Currency plural name is not a fixed static one,
+        // it is a dynamic name based on the currency plural count.
+        // So, the affixes need to be expanded here.
+        // For other cases, the affix is a static one based on pattern alone,
+        // and it is already expanded during applying pattern,
+        // or setDecimalFormatSymbols, or setCurrency.
+        expandAffixAdjustWidth(pluralCount);
+        return subformat(result, fieldPosition, isNegative, isInteger, parseAttr);
+    }
+
+    /**
+     * Complete the formatting of a finite number.  On entry, the digitList must
+     * be filled in with the correct digits.
+     */
+    private StringBuffer subformat(StringBuffer result,
+            FieldPosition fieldPosition, boolean isNegative, boolean isInteger,
+            boolean parseAttr) 
+    {
+        // NOTE: This isn't required anymore because DigitList takes care of this.
+        //
+        //  // The negative of the exponent represents the number of leading
+        //  // zeros between the decimal and the first non-zero digit, for
+        //  // a value < 0.1 (e.g., for 0.00123, -fExponent == 2).  If this
+        //  // is more than the maximum fraction digits, then we have an underflow
+        //  // for the printed representation.  We recognize this here and set
+        //  // the DigitList representation to zero in this situation.
+        //
+        //  if (-digitList.decimalAt >= getMaximumFractionDigits())
+        //  {
+        //      digitList.count = 0;
+        //  }
+
+        int i;
+        char zero = symbols.getZeroDigit();
+        int zeroDelta = zero - '0'; // '0' is the DigitList representation of zero
+        char grouping = currencySignCount > 0 ?
+                    symbols.getMonetaryGroupingSeparator() :
+                    symbols.getGroupingSeparator();
+        char decimal =  currencySignCount > 0 ?
+            symbols.getMonetaryDecimalSeparator() :
+            symbols.getDecimalSeparator();
+        boolean useSigDig = areSignificantDigitsUsed();
+        int maxIntDig = getMaximumIntegerDigits();
+        int minIntDig = getMinimumIntegerDigits();
+
+        /* Per bug 4147706, DecimalFormat must respect the sign of numbers which
+         * format as zero.  This allows sensible computations and preserves
+         * relations such as signum(1/x) = signum(x), where x is +Infinity or
+         * -Infinity.  Prior to this fix, we always formatted zero values as if
+         * they were positive.  Liu 7/6/98.
+         */
+        if (digitList.isZero())
+        {
+            digitList.decimalAt = 0; // Normalize
+        }
+
+        int prefixLen = appendAffix(result, isNegative, true, parseAttr);
+
+        if (useExponentialNotation)
+        {
+            // Record field information for caller.
+            if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD) {
+                fieldPosition.setBeginIndex(result.length());
+                fieldPosition.setEndIndex(-1);
+            } else if (fieldPosition.getField() == NumberFormat.FRACTION_FIELD) {
+                fieldPosition.setBeginIndex(-1);
+            }
+//#if defined(FOUNDATION10) || defined(J2SE13) 
+//#else 
+            else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {
+                fieldPosition.setBeginIndex(result.length());
+                fieldPosition.setEndIndex(-1);
+            } else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.FRACTION) {
+                fieldPosition.setBeginIndex(-1);
+            } 
+//#endif 
+
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+            // [Spark/CDL]
+            // the begin index of integer part
+            // the end index of integer part
+            // the begin index of fractional part
+            int intBegin = result.length();
+            int intEnd = -1;
+            int fracBegin = -1;
+//#endif
+
+            int minFracDig = 0;
+            if (useSigDig) {
+                maxIntDig = minIntDig = 1;
+                minFracDig = getMinimumSignificantDigits() - 1;
+            } else {
+                minFracDig = getMinimumFractionDigits();
+                if (maxIntDig > MAX_SCIENTIFIC_INTEGER_DIGITS) {
+                    maxIntDig = 1;
+                    if (maxIntDig < minIntDig) {
+                        maxIntDig = minIntDig;
+                    }
+                }
+                if (maxIntDig > minIntDig) {
+                    minIntDig = 1;
+                }
+            }            
+
+            // Minimum integer digits are handled in exponential format by
+            // adjusting the exponent.  For example, 0.01234 with 3 minimum
+            // integer digits is "123.4E-4".
+
+            // Maximum integer digits are interpreted as indicating the
+            // repeating range.  This is useful for engineering notation, in
+            // which the exponent is restricted to a multiple of 3.  For
+            // example, 0.01234 with 3 maximum integer digits is "12.34e-3".
+            // If maximum integer digits are defined and are larger than
+            // minimum integer digits, then minimum integer digits are
+            // ignored.
+
+            int exponent = digitList.decimalAt;
+            if (maxIntDig > 1 && maxIntDig != minIntDig) {
+                // A exponent increment is defined; adjust to it.
+                exponent = (exponent > 0) ? (exponent - 1) / maxIntDig
+                                          : (exponent / maxIntDig) - 1;
+                exponent *= maxIntDig;
+            } else {
+                // No exponent increment is defined; use minimum integer digits.
+                // If none is specified, as in "#E0", generate 1 integer digit.
+                exponent -= (minIntDig > 0 || minFracDig > 0)
+                    ? minIntDig : 1;
+            }
+
+            // We now output a minimum number of digits, and more if there
+            // are more digits, up to the maximum number of digits.  We
+            // place the decimal point after the "integer" digits, which
+            // are the first (decimalAt - exponent) digits.
+            int minimumDigits = minIntDig + minFracDig;
+            // The number of integer digits is handled specially if the number
+            // is zero, since then there may be no digits.
+            int integerDigits = digitList.isZero() ? minIntDig :
+                digitList.decimalAt - exponent;
+            int totalDigits = digitList.count;
+            if (minimumDigits > totalDigits) totalDigits = minimumDigits;
+            if (integerDigits > totalDigits) totalDigits = integerDigits;
+
+            for (i=0; i<totalDigits; ++i)
+            {
+                if (i == integerDigits)
+                {
+                    // Record field information for caller.
+                    if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD) {
+                        fieldPosition.setEndIndex(result.length());
+                    }
+//#if defined(FOUNDATION10) || defined(J2SE13) 
+//#else 
+                    else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {
+                        fieldPosition.setEndIndex(result.length());
+                    }
+//#endif 
+
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+                    // [Spark/CDL] Add attribute for integer part
+                    if (parseAttr) {
+                        intEnd = result.length();
+                        addAttribute(Field.INTEGER, intBegin, result.length());
+                    }
+//#endif
+                    result.append(decimal);
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+                    // [Spark/CDL] Add attribute for decimal separator
+                    if (parseAttr) {
+                        // Length of decimal separator is 1.
+                        int decimalSeparatorBegin = result.length() - 1;
+                        addAttribute(Field.DECIMAL_SEPARATOR,
+                                decimalSeparatorBegin, result.length());
+                            fracBegin = result.length();
+                    }
+//#endif
+                    // Record field information for caller.
+                    if (fieldPosition.getField() == NumberFormat.FRACTION_FIELD) {
+                        fieldPosition.setBeginIndex(result.length());
+                    }
+//#if defined(FOUNDATION10) || defined(J2SE13) 
+//#else 
+                    else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.FRACTION) {
+                        fieldPosition.setBeginIndex(result.length());
+                    }
+//#endif 
+
+                }
+                result.append((i < digitList.count) ?
+                          (char)(digitList.digits[i] + zeroDelta) :
+                          zero);
+            }
+            
+            //For ICU compatibility and format 0 to 0E0 with pattern "#E0" [Richard/GCL]
+            if (digitList.isZero() && (totalDigits ==0)) {
+                result.append(zero);
+            }
+
+            // Record field information
+            if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD) {
+                if (fieldPosition.getEndIndex() < 0) {
+                    fieldPosition.setEndIndex(result.length());
+                }
+            } else if (fieldPosition.getField() == NumberFormat.FRACTION_FIELD) {
+                if (fieldPosition.getBeginIndex() < 0) {
+                    fieldPosition.setBeginIndex(result.length());
+                }
+                fieldPosition.setEndIndex(result.length());
+            }
+//#if defined(FOUNDATION10) || defined(J2SE13) 
+//#else 
+            else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {
+                if (fieldPosition.getEndIndex() < 0) {
+                    fieldPosition.setEndIndex(result.length());
+                }
+            } else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.FRACTION) {
+                if (fieldPosition.getBeginIndex() < 0) {
+                    fieldPosition.setBeginIndex(result.length());
+                }
+                fieldPosition.setEndIndex(result.length());
+            }
+//#endif 
+
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+            // [Spark/CDL] Calcuate the end index of integer part and fractional
+            // part if they are not properly processed yet.
+            if (parseAttr) {
+                if (intEnd < 0) {
+                    addAttribute(Field.INTEGER, intBegin, result.length());
+                }
+                if (fracBegin > 0) {
+                    addAttribute(Field.FRACTION, fracBegin, result.length());
+                }
+            }
+//#endif
+
+            // The exponent is output using the pattern-specified minimum
+            // exponent digits.  There is no maximum limit to the exponent
+            // digits, since truncating the exponent would result in an
+            // unacceptable inaccuracy.
+            result.append(symbols.getExponentSeparator());
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+            // [Spark/CDL] For exponent symbol, add an attribute.
+            if (parseAttr) {
+                addAttribute(Field.EXPONENT_SYMBOL, result.length()
+                        - symbols.getExponentSeparator().length(), result
+                        .length());
+            }
+//#endif
+            // For zero values, we force the exponent to zero.  We
+            // must do this here, and not earlier, because the value
+            // is used to determine integer digit count above.
+            if (digitList.isZero()) exponent = 0;
+
+            boolean negativeExponent = exponent < 0;
+            if (negativeExponent) {
+                exponent = -exponent;
+                result.append(symbols.getMinusSign());
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+                // [Spark/CDL] If exponent has sign, then add an exponent sign
+                // attribute.
+                if (parseAttr) {
+                    // Length of exponent sign is 1.
+                    addAttribute(Field.EXPONENT_SIGN, result.length() - 1,
+                            result.length());
+                }
+//#endif
+            } else if (exponentSignAlwaysShown) {
+                result.append(symbols.getPlusSign());
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+                // [Spark/CDL] Add an plus sign attribute.
+                if (parseAttr) {
+                    // Length of exponent sign is 1.
+                    int expSignBegin = result.length() - 1;
+                    addAttribute(Field.EXPONENT_SIGN, expSignBegin, result
+                            .length());
+                }
+//#endif
+            }
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+            int expBegin = result.length();
+//#endif
+            digitList.set(exponent);
+            {
+                int expDig = minExponentDigits;
+                if (useExponentialNotation && expDig < 1) {
+                    expDig = 1;
+                }
+                for (i=digitList.decimalAt; i<expDig; ++i) result.append(zero);
+            }
+            for (i=0; i<digitList.decimalAt; ++i)
+            {
+                result.append((i < digitList.count) ?
+                          (char)(digitList.digits[i] + zeroDelta) : zero);
+            }
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+            // [Spark/CDL] Add attribute for exponent part.
+            if (parseAttr) {
+                addAttribute(Field.EXPONENT, expBegin, result.length());
+            }
+//#endif
+        }
+        else
+        {
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+            // [Spark/CDL] Record the integer start index.
+            int intBegin = result.length();
+//#endif
+            // Record field information for caller.
+            if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD) {
+                fieldPosition.setBeginIndex(result.length());
+            }
+//#if defined(FOUNDATION10) || defined(J2SE13) 
+//#else 
+            else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {
+                fieldPosition.setBeginIndex(result.length());
+            }
+//#endif 
+
+            int sigCount = 0;
+            int minSigDig = getMinimumSignificantDigits();
+            int maxSigDig = getMaximumSignificantDigits();
+            if (!useSigDig) {
+                minSigDig = 0;
+                maxSigDig = Integer.MAX_VALUE;
+            }
+
+            // Output the integer portion.  Here 'count' is the total
+            // number of integer digits we will display, including both
+            // leading zeros required to satisfy getMinimumIntegerDigits,
+            // and actual digits present in the number.
+            int count = useSigDig ?
+                Math.max(1, digitList.decimalAt) : minIntDig;
+            if (digitList.decimalAt > 0 && count < digitList.decimalAt) {
+                count = digitList.decimalAt;
+            }
+
+            // Handle the case where getMaximumIntegerDigits() is smaller
+            // than the real number of integer digits.  If this is so, we
+            // output the least significant max integer digits.  For example,
+            // the value 1997 printed with 2 max integer digits is just "97".
+
+            int digitIndex = 0; // Index into digitList.fDigits[]
+            if (count > maxIntDig && maxIntDig >= 0) {
+                count = maxIntDig;
+                digitIndex = digitList.decimalAt - count;
+            }
+
+            int sizeBeforeIntegerPart = result.length();
+            for (i=count-1; i>=0; --i)
+            {
+                if (i < digitList.decimalAt && digitIndex < digitList.count &&
+                    sigCount < maxSigDig) {
+                    // Output a real digit
+                    byte d = digitList.digits[digitIndex++];
+                    result.append((char)(d + zeroDelta));
+                    ++sigCount;
+                }
+                else
+                {
+                    // Output a zero (leading or trailing)
+                    result.append(zero);
+                    if (sigCount > 0) {
+                        ++sigCount;
+                    }
+                }
+
+                // Output grouping separator if necessary.
+                if (isGroupingPosition(i)) {
+                    result.append(grouping);
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+                    // [Spark/CDL] Add grouping separator attribute here.
+                    if (parseAttr) {
+                        // Length of grouping separator is 1.
+                        addAttribute(Field.GROUPING_SEPARATOR,
+                                result.length() - 1, result.length());
+                    }
+//#endif
+                }
+            }
+
+            // Record field information for caller.
+            if (fieldPosition.getField() == NumberFormat.INTEGER_FIELD) {
+                fieldPosition.setEndIndex(result.length());
+            }
+//#if defined(FOUNDATION10) || defined(J2SE13) 
+//#else 
+            else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.INTEGER) {
+                fieldPosition.setEndIndex(result.length());
+            }
+//#endif 
+
+            // Determine whether or not there are any printable fractional
+            // digits.  If we've used up the digits we know there aren't.
+            boolean fractionPresent = (!isInteger && digitIndex < digitList.count) ||
+                (useSigDig ? (sigCount < minSigDig) : (getMinimumFractionDigits() > 0));
+
+            // If there is no fraction present, and we haven't printed any
+            // integer digits, then print a zero.  Otherwise we won't print
+            // _any_ digits, and we won't be able to parse this string.
+            if (!fractionPresent && result.length() == sizeBeforeIntegerPart)
+                result.append(zero);
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+            // [Spark/CDL] Add attribute for integer part.
+            if (parseAttr) {
+                addAttribute(Field.INTEGER, intBegin, result.length());
+            }
+//#endif
+            // Output the decimal separator if we always do so.
+            if (decimalSeparatorAlwaysShown || fractionPresent)
+            {
+                result.append(decimal);
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+                // [Spark/CDL] Add attribute for decimal separator
+                if (parseAttr) {
+                    addAttribute(Field.DECIMAL_SEPARATOR, result.length() - 1,
+                            result.length());
+                }
+//#endif
+            }
+
+            // Record field information for caller.
+            if (fieldPosition.getField() == NumberFormat.FRACTION_FIELD) {
+                fieldPosition.setBeginIndex(result.length());
+            }
+//#if defined(FOUNDATION10) || defined(J2SE13) 
+//#else 
+            else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.FRACTION) {
+                fieldPosition.setBeginIndex(result.length());
+            }
+//#endif 
+
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+            // [Spark/CDL] Record the begin index of fraction part.
+            int fracBegin = result.length();
+//#endif
+
+            count = useSigDig ? Integer.MAX_VALUE : getMaximumFractionDigits();
+            if (useSigDig && (sigCount == maxSigDig ||
+                              (sigCount >= minSigDig && digitIndex == digitList.count))) {
+                count = 0;   
+            }
+            for (i=0; i < count; ++i) {
+                // Here is where we escape from the loop.  We escape
+                // if we've output the maximum fraction digits
+                // (specified in the for expression above).  We also
+                // stop when we've output the minimum digits and
+                // either: we have an integer, so there is no
+                // fractional stuff to display, or we're out of
+                // significant digits.
+                if (!useSigDig && i >= getMinimumFractionDigits() &&
+                    (isInteger || digitIndex >= digitList.count)) {
+                    break;
+                }
+
+                // Output leading fractional zeros.  These are zeros
+                // that come after the decimal but before any
+                // significant digits.  These are only output if
+                // abs(number being formatted) < 1.0.
+                if (-1-i > (digitList.decimalAt-1)) {
+                    result.append(zero);
+                    continue;
+                }
+
+                // Output a digit, if we have any precision left, or a
+                // zero if we don't.  We don't want to output noise digits.
+                if (!isInteger && digitIndex < digitList.count) {
+                    result.append((char)(digitList.digits[digitIndex++] + zeroDelta));
+                } else {
+                    result.append(zero);
+                }
+
+                // If we reach the maximum number of significant
+                // digits, or if we output all the real digits and
+                // reach the minimum, then we are done.
+                ++sigCount;
+                if (useSigDig &&
+                    (sigCount == maxSigDig ||
+                     (digitIndex == digitList.count && sigCount >= minSigDig))) {
+                    break;
+                }
+            }
+
+            // Record field information for caller.
+            if (fieldPosition.getField() == NumberFormat.FRACTION_FIELD) {
+                fieldPosition.setEndIndex(result.length());
+            }
+//#if defined(FOUNDATION10) || defined(J2SE13) 
+//#else 
+            else if (fieldPosition.getFieldAttribute() == NumberFormat.Field.FRACTION) {
+                fieldPosition.setEndIndex(result.length());
+            }
+//#endif 
+
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+            // [Spark/CDL] Add attribute information if necessary.
+            if (parseAttr && (decimalSeparatorAlwaysShown || fractionPresent)) {
+                addAttribute(Field.FRACTION, fracBegin, result.length());
+            }
+//#endif
+        }
+
+        int suffixLen = appendAffix(result, isNegative, false, parseAttr);
+
+        // [NEW]
+        addPadding(result, fieldPosition, prefixLen, suffixLen);
+        return result;
+    }
+
+    // [NEW]
+    private final void addPadding(StringBuffer result, FieldPosition fieldPosition,
+                                  int prefixLen, int suffixLen) {
+        if (formatWidth > 0) {
+            int len = formatWidth - result.length();
+            if (len > 0) {
+                char[] padding = new char[len];
+                for (int i=0; i<len; ++i) {
+                    padding[i] = pad;
+                }
+                switch (padPosition) {
+                case PAD_AFTER_PREFIX:
+                    result.insert(prefixLen, padding);
+                    break;
+                case PAD_BEFORE_PREFIX:
+                    result.insert(0, padding);
+                    break;
+                case PAD_BEFORE_SUFFIX:
+                    result.insert(result.length() - suffixLen, padding);
+                    break;
+                case PAD_AFTER_SUFFIX:
+                    result.append(padding);
+                    break;
+                }
+                if (padPosition == PAD_BEFORE_PREFIX ||
+                    padPosition == PAD_AFTER_PREFIX) {
+                    fieldPosition.setBeginIndex(fieldPosition.getBeginIndex() + len);
+                    fieldPosition.setEndIndex(fieldPosition.getEndIndex() + len);
+                }
+            }
+        }
+    }
+
+    // [CHANGED]
+    /**
+     * Parse the given string, returning a <code>Number</code> object to
+     * represent the parsed value.  <code>Double</code> objects are returned to
+     * represent non-integral values which cannot be stored in a
+     * <code>BigDecimal</code>.  These are <code>NaN</code>, infinity,
+     * -infinity, and -0.0.  If {@link #isParseBigDecimal()} is false (the
+     * default), all other values are returned as <code>Long</code>,
+     * <code>BigInteger</code>, or <code>BigDecimal</code> values,
+     * in that order of preference. If {@link #isParseBigDecimal()} is true,
+     * all other values are returned as <code>BigDecimal</code> valuse.
+     * If the parse fails, null is returned.
+     * @param text the string to be parsed
+     * @param parsePosition defines the position where parsing is to begin,
+     * and upon return, the position where parsing left off.  If the position
+     * has not changed upon return, then parsing failed.
+     * @return a <code>Number</code> object with the parsed value or
+     * <code>null</code> if the parse failed
+     * @stable ICU 2.0
+     */
+    public Number parse(String text, ParsePosition parsePosition) {
+       return (Number) parse(text, parsePosition, false);
+    }
+
+    // [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) {
+        return (CurrencyAmount) parse(text, pos, true);
+    }
+
+    /**
+     * Parses the given text as either a Number or a CurrencyAmount.
+     * @param text the string to parse
+     * @param parsePosition 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.
+     * @param parseCurrency if true, a CurrencyAmount is parsed and
+     * returned; otherwise a Number is parsed and returned
+     * @return a Number or CurrencyAmount or null
+     */
+    private Object parse(String text, ParsePosition parsePosition, boolean parseCurrency) {
+        int backup;
+        int i = backup = parsePosition.getIndex();
+
+        // Handle NaN as a special case:
+
+        // Skip padding characters, if around prefix
+        if (formatWidth > 0 && (padPosition == PAD_BEFORE_PREFIX ||
+                                padPosition == PAD_AFTER_PREFIX)) {
+            i = skipPadding(text, i);
+        }
+        if (text.regionMatches(i, symbols.getNaN(),
+                               0, symbols.getNaN().length())) {
+            i += symbols.getNaN().length();
+            // Skip padding characters, if around suffix
+            if (formatWidth > 0 && (padPosition == PAD_BEFORE_SUFFIX ||
+                                    padPosition == PAD_AFTER_SUFFIX)) {
+                i = skipPadding(text, i);
+            }
+            parsePosition.setIndex(i);
+            return new Double(Double.NaN);
+        }
+
+        // NaN parse failed; start over
+        i = backup;
+
+        boolean[] status = new boolean[STATUS_LENGTH];
+        Currency[] currency = parseCurrency ? new Currency[1] : null;
+        if (currencySignCount > 0) {
+            if (!parseForCurrency(text, parsePosition, parseCurrency, 
+                                  currency, status)) {
+                return null;
+            }
+        } else {
+            if (!subparse(text, parsePosition, digitList, false, status, 
+                          currency, negPrefixPattern, negSuffixPattern,
+                          posPrefixPattern, posSuffixPattern, Currency.SYMBOL_NAME)) {
+                parsePosition.setIndex(backup);
+                return null;
+            }
+        }
+
+        Number n = null;
+
+        // Handle infinity
+        if (status[STATUS_INFINITE]) {
+            n = new Double(status[STATUS_POSITIVE]
+                           ? Double.POSITIVE_INFINITY
+                           : Double.NEGATIVE_INFINITY);
+        }
+
+        // Handle underflow
+        else if (status[STATUS_UNDERFLOW]) {
+            n = status[STATUS_POSITIVE] ? new Double("0.0") : new Double("-0.0");
+        }
+
+        // Handle -0.0
+        else if (!status[STATUS_POSITIVE] && digitList.isZero()) {
+            n = new Double("-0.0");
+        }
+
+        else {
+            // Do as much of the multiplier conversion as possible without
+            // losing accuracy.
+            int mult = multiplier; // Don't modify this.multiplier
+            while (mult % 10 == 0) {
+                --digitList.decimalAt;
+                mult /= 10;
+            }
+
+            // Handle integral values
+            if (!parseBigDecimal && mult == 1 && digitList.isIntegral()) {
+                // hack quick long
+                if (digitList.decimalAt < 12) { // quick check for long
+                    long l = 0;
+                    if (digitList.count > 0) {
+                        int nx = 0;
+                        while (nx < digitList.count) {
+                            l = l * 10 + (char)digitList.digits[nx++] - '0';
+                        }
+                        while (nx++ < digitList.decimalAt) {
+                            l *= 10;
+                        }
+                        if (!status[STATUS_POSITIVE]) {
+                            l = -l;
+                        }
+                    }
+                    n = new Long(l);
+                } else {
+                    BigInteger big = digitList.getBigInteger(status[STATUS_POSITIVE]);
+                    n = (big.bitLength() < 64) ?
+                        (Number) new Long(big.longValue()) : (Number) big;
+                }
+            }
+            // Handle non-integral values or the case where parseBigDecimal is set
+            else {
+                BigDecimal big = digitList.getBigDecimalICU(status[STATUS_POSITIVE]);
+                n = big;
+                if (mult != 1) {
+                    n = big.divide(BigDecimal.valueOf(mult), mathContext);
+                }
+            }
+        }
+
+        // Assemble into CurrencyAmount if necessary
+        return parseCurrency ? (Object) new CurrencyAmount(n, currency[0])
+                             : (Object) n;
+    }
+
+
+    private boolean parseForCurrency(String text, ParsePosition parsePosition, 
+                                     boolean parseCurrency, Currency[] currency,
+                                     boolean[] status) {
+        int origPos = parsePosition.getIndex();
+        if (!isReadyForParsing) {
+            int savedCurrencySignCount = currencySignCount;
+            setupCurrencyAffixForAllPatterns();
+            // reset pattern back
+            if (savedCurrencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT) {
+                applyPatternWithoutExpandAffix(formatPattern, false);
+            } else {
+                applyPattern(formatPattern, false);
+            }
+            isReadyForParsing = true;
+        }
+        int maxPosIndex = origPos;
+        int maxErrorPos = -1;
+        boolean[] savedStatus = null;
+        // First, parse against current pattern.
+        // Since current pattern could be set by applyPattern(),
+        // it could be an arbitrary pattern, and it may not be the one
+        // defined in current locale.
+        boolean[] tmpStatus = new boolean[STATUS_LENGTH];
+        ParsePosition tmpPos = new ParsePosition(origPos);
+        DigitList tmpDigitList = new DigitList();
+        boolean found;
+        if (style == NumberFormat.PLURALCURRENCYSTYLE) {
+            found  = subparse(text, tmpPos, tmpDigitList, false, 
+                  tmpStatus, currency, negPrefixPattern, negSuffixPattern,
+                  posPrefixPattern, posSuffixPattern, Currency.LONG_NAME);
+        } else {
+            found  = subparse(text, tmpPos, tmpDigitList, false, 
+                  tmpStatus, currency, negPrefixPattern, negSuffixPattern,
+                  posPrefixPattern, posSuffixPattern, Currency.SYMBOL_NAME);
+        }
+        if (found) {
+            if (tmpPos.getIndex() > maxPosIndex) {
+                maxPosIndex = tmpPos.getIndex();
+                savedStatus = tmpStatus;
+                digitList = tmpDigitList;
+            }
+        } else {
+            maxErrorPos = tmpPos.getErrorIndex();
+        }
+        // Then, parse against affix patterns.
+        // Those are currency patterns and currency plural patterns
+        // defined in the locale.
+        Iterator  iter = affixPatternsForCurrency.iterator();
+        while (iter.hasNext()) {
+            AffixForCurrency affix = (AffixForCurrency)iter.next();
+
+            tmpStatus = new boolean[STATUS_LENGTH];
+            tmpPos = new ParsePosition(origPos); 
+            tmpDigitList = new DigitList();
+            boolean result = subparse(text, tmpPos, tmpDigitList, false, 
+                               tmpStatus, currency, affix.getNegPrefix(),
+                               affix.getNegSuffix(), affix.getPosPrefix(), 
+                               affix.getPosSuffix(), affix.getPatternType());
+            if (result) {
+                found = true;
+                if (tmpPos.getIndex() > maxPosIndex) {
+                    maxPosIndex = tmpPos.getIndex();
+                    savedStatus = tmpStatus;
+                    digitList = tmpDigitList;
+                }
+            } else {
+                maxErrorPos = (tmpPos.getErrorIndex() > maxErrorPos) ?
+                              tmpPos.getErrorIndex() : maxErrorPos;
+            }
+        }
+        // Finally, parse against simple affix to find the match.
+        // For example, in TestMonster suite,
+        // if the to-be-parsed text is "-\u00A40,00".
+        // complexAffixCompare will not find match,
+        // since there is no ISO code matches "\u00A4",
+        // and the parse stops at "\u00A4".
+        // We will just use simple affix comparison (look for exact match)
+        // to pass it.
+        tmpStatus = new boolean[STATUS_LENGTH];
+        tmpPos = new ParsePosition(origPos); 
+        tmpDigitList = new DigitList();
+        int savedCurrencySignCount = currencySignCount;
+        // set currencySignCount to 0 so that compareAffix function will
+        // fall to compareSimpleAffix path, not compareComplexAffix path.
+        currencySignCount = 0;
+        boolean result = subparse(text, tmpPos, tmpDigitList, false, 
+                  tmpStatus, currency, negativePrefix, negativeSuffix,
+                  positivePrefix, positiveSuffix, Currency.SYMBOL_NAME);
+        currencySignCount = savedCurrencySignCount;
+        if (result) {
+            if (tmpPos.getIndex() > maxPosIndex) {
+                maxPosIndex = tmpPos.getIndex();
+                savedStatus = tmpStatus;
+                digitList = tmpDigitList;
+            }
+            found = true;
+        } else {
+                maxErrorPos = (tmpPos.getErrorIndex() > maxErrorPos) ?
+                              tmpPos.getErrorIndex() : maxErrorPos;
+        }
+
+        if (!found) {
+            //parsePosition.setIndex(origPos);
+            parsePosition.setErrorIndex(maxErrorPos);
+        } else {
+            parsePosition.setIndex(maxPosIndex);
+            parsePosition.setErrorIndex(-1);
+            for (int index = 0; index < STATUS_LENGTH; ++index) {
+                status[index] = savedStatus[index];
+            }
+        }
+        return found;
+    }
+
+
+    // Get affix patterns used in locale's currency pattern
+    // (NumberPatterns[1]) and currency plural pattern (CurrencyUnitPatterns).
+    private void setupCurrencyAffixForAllPatterns() {
+        if (currencyPluralInfo == null) {
+            currencyPluralInfo = new CurrencyPluralInfo(symbols.getLocale());
+        }
+        affixPatternsForCurrency = new HashSet();
+
+        // save the current pattern, since it will be changed by
+        // applyPatternWithoutExpandAffix
+        String savedFormatPattern = formatPattern;
+        
+        // CURRENCYSTYLE and ISOCURRENCYSTYLE should have the same
+        // prefix and suffix, so, only need to save one of them.
+        // Here, chose onlyApplyPatternWithoutExpandAffix without
+        // saving the actualy pattern in 'pattern' data member.
+        // TODO: is it uloc?
+        applyPatternWithoutExpandAffix(getPattern(symbols.getLocale(), NumberFormat.CURRENCYSTYLE), false);
+        AffixForCurrency affixes = new AffixForCurrency(negPrefixPattern,
+                                                        negSuffixPattern,
+                                                        posPrefixPattern,
+                                                        posSuffixPattern,
+                                                        Currency.SYMBOL_NAME);
+        affixPatternsForCurrency.add(affixes);
+        
+        // add plural pattern
+        Iterator iter = currencyPluralInfo.pluralPatternIterator();
+        Set currencyUnitPatternSet = new HashSet();
+        while (iter.hasNext()) {
+            String pluralCount = (String)iter.next();
+            String currencyPattern = (String)currencyPluralInfo.getCurrencyPluralPattern(pluralCount);
+            if (currencyPattern != null &&
+                currencyUnitPatternSet.contains(currencyPattern) == false) {
+                currencyUnitPatternSet.add(currencyPattern);
+                applyPatternWithoutExpandAffix(currencyPattern, false);
+                affixes = new AffixForCurrency(negPrefixPattern,
+                                               negSuffixPattern,
+                                               posPrefixPattern,
+                                               posSuffixPattern,
+                                               Currency.LONG_NAME);
+                affixPatternsForCurrency.add(affixes);
+            }   
+        }
+        // reset pattern back
+        formatPattern = savedFormatPattern;
+    }
+
+    private static final int CURRENCY_SIGN_COUNT_IN_SYMBOL_FORMAT = 1;
+    private static final int CURRENCY_SIGN_COUNT_IN_ISO_FORMAT = 2;
+    private static final int CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT = 3;
+
+    private static final int STATUS_INFINITE = 0;
+    private static final int STATUS_POSITIVE = 1;
+    private static final int STATUS_UNDERFLOW = 2;
+    private static final int STATUS_LENGTH   = 3;
+    private static final UnicodeSet dotEquivalents =(UnicodeSet) new UnicodeSet(
+        "[.\u2024\u3002\uFE12\uFE52\uFF0E\uFF61]").freeze();
+    private static final UnicodeSet commaEquivalents = (UnicodeSet) new UnicodeSet(
+        "[,\u060C\u066B\u3001\uFE10\uFE11\uFE50\uFE51\uFF0C\uFF64]").freeze();
+    private static final UnicodeSet otherGroupingSeparators = (UnicodeSet) new UnicodeSet(
+        "[\\ '\u00A0\u066C\u2000-\u200A\u2018\u2019\u202F\u205F\u3000\uFF07]").freeze();
+    
+    private static final UnicodeSet strictDotEquivalents =(UnicodeSet) new UnicodeSet(
+        "[.\u2024\uFE52\uFF0E\uFF61]").freeze();
+    private static final UnicodeSet strictCommaEquivalents = (UnicodeSet) new UnicodeSet(
+        "[,\u066B\uFE10\uFE50\uFF0C]").freeze();
+    private static final UnicodeSet strictOtherGroupingSeparators = (UnicodeSet) new UnicodeSet(
+        "[\\ '\u00A0\u066C\u2000-\u200A\u2018\u2019\u202F\u205F\u3000\uFF07]").freeze();
+
+    private static final UnicodeSet defaultGroupingSeparators = (UnicodeSet) new UnicodeSet(
+        dotEquivalents).addAll(commaEquivalents).addAll(otherGroupingSeparators).freeze();
+    private static final UnicodeSet strictDefaultGroupingSeparators = (UnicodeSet) new UnicodeSet(
+            strictDotEquivalents).addAll(strictCommaEquivalents).addAll(strictOtherGroupingSeparators).freeze();
+
+    // When parsing a number with big exponential value, it requires to transform
+    // the value into a string representation to construct BigInteger instance.
+    // We want to set the maximum size because it can easily trigger OutOfMemoryException.
+    // PARSE_MAX_EXPONENT is currently set to 1000, which is much bigger than
+    // MAX_VALUE of Double (
+    // See the problem reported by ticket#5698
+    private static final int PARSE_MAX_EXPONENT = 1000;
+
+    /**
+     * <strong><font face=helvetica color=red>CHANGED</font></strong>
+     * Parse the given text into a number.  The text is parsed beginning at
+     * parsePosition, until an unparseable character is seen.
+     * @param text The string to parse.
+     * @param parsePosition The position at which to being parsing.  Upon
+     * return, the first unparseable character.
+     * @param digits The DigitList to set to the parsed value.
+     * @param isExponent If true, parse an exponent.  This means no
+     * infinite values and integer only.
+     * @param status Upon return contains boolean status flags indicating
+     * whether the value was infinite and whether it was positive.
+     * @param currency return value for parsed currency, for generic
+     * currency parsing mode, or null for normal parsing. In generic
+     * currency parsing mode, any currency is parsed, not just the
+     * currency that this formatter is set to.
+     * @param negPrefix negative prefix pattern
+     * @param negSuffix negative suffix pattern
+     * @param posPrefix positive prefix pattern
+     * @param negSuffix negative suffix pattern
+     * @param type type of currency to parse against, LONG_NAME only or not.
+     */
+    private final boolean subparse(String text, ParsePosition parsePosition,
+                   DigitList digits, boolean isExponent,
+                   boolean status[], Currency currency[],
+                   String negPrefix, String negSuffix,
+                   String posPrefix, String posSuffix,
+                   int type)
+    {
+        int position = parsePosition.getIndex();
+        int oldStart = parsePosition.getIndex();
+
+        // Match padding before prefix
+        if (formatWidth > 0 && padPosition == PAD_BEFORE_PREFIX) {
+            position = skipPadding(text, position);
+        }
+
+        // Match positive and negative prefixes; prefer longest match.
+        int posMatch = compareAffix(text, position, false, true, posPrefix, type, currency);
+        int negMatch = compareAffix(text, position, true, true, negPrefix, type, currency);
+        if (posMatch >= 0 && negMatch >= 0) {
+            if (posMatch > negMatch) {
+                negMatch = -1;
+            } else if (negMatch > posMatch) {
+                posMatch = -1;
+            }  
+        }
+        if (posMatch >= 0) {
+            position += posMatch;
+        } else if (negMatch >= 0) {
+            position += negMatch;
+        } else {
+            parsePosition.setErrorIndex(position);
+            return false;
+        }
+
+        // Match padding after prefix
+        if (formatWidth > 0 && padPosition == PAD_AFTER_PREFIX) {
+            position = skipPadding(text, position);
+        }
+
+        // process digits or Inf, find decimal position
+        status[STATUS_INFINITE] = false;
+        if (!isExponent && text.regionMatches(position,symbols.getInfinity(),0,
+                          symbols.getInfinity().length()))
+        {
+            position += symbols.getInfinity().length();
+            status[STATUS_INFINITE] = true;
+        } else {
+            // We now have a string of digits, possibly with grouping symbols,
+            // and decimal points.  We want to process these into a DigitList.
+            // We don't want to put a bunch of leading zeros into the DigitList
+            // though, so we keep track of the location of the decimal point,
+            // put only significant digits into the DigitList, and adjust the
+            // exponent as needed.
+
+            digits.decimalAt = digits.count = 0;
+            char zero = symbols.getZeroDigit();
+            char decimal = currencySignCount > 0 ?
+            symbols.getMonetaryDecimalSeparator() : symbols.getDecimalSeparator();
+            char grouping = symbols.getGroupingSeparator();
+                        
+            String exponentSep = symbols.getExponentSeparator();
+            boolean sawDecimal = false;
+            boolean sawExponent = false;
+            boolean sawDigit = false;
+            long exponent = 0; // Set to the exponent value, if any
+            int digit = 0;
+
+            // strict parsing
+            boolean strictParse = isParseStrict();
+            boolean strictFail = false; // did we exit with a strict parse failure?
+            int lastGroup = -1; // where did we last see a grouping separator?
+            int gs2 = groupingSize2 == 0 ? groupingSize : groupingSize2;
+
+            // Strict parsing leading zeroes.  If a leading zero would
+            // be forced by the pattern, then don't fail strict parsing.
+            boolean strictLeadingZero = false;
+            int leadingZeroPos   = 0;
+            int leadingZeroCount = 0;
+            
+            // equivalent grouping and decimal support
+            
+            // TODO markdavis Cache these if it makes a difference in performance.
+            UnicodeSet decimalSet = new UnicodeSet(getSimilarDecimals(decimal, strictParse));
+            UnicodeSet groupingSet = new UnicodeSet(strictParse ? strictDefaultGroupingSeparators : defaultGroupingSeparators)
+                .add(grouping).removeAll(decimalSet);
+            
+            // we are guaranteed that 
+            // decimalSet contains the decimal, and 
+            // groupingSet contains the groupingSeparator
+            // (unless decimal and grouping are the same, which should never happen. But in that case, groupingSet will just be empty.)
+
+
+            // We have to track digitCount ourselves, because digits.count will
+            // pin when the maximum allowable digits is reached.
+            int digitCount = 0;
+            
+            int backup = -1;
+            for (; position < text.length(); ++position)
+            {
+                char ch = text.charAt(position);
+
+                /* We recognize all digit ranges, not only the Latin digit range
+                 * '0'..'9'.  We do so by using the UCharacter.digit() method,
+                 * which converts a valid Unicode digit to the range 0..9.
+                 *
+                 * The character 'ch' may be a digit.  If so, place its value
+                 * from 0 to 9 in 'digit'.  First try using the locale digit,
+                 * which may or MAY NOT be a standard Unicode digit range.  If
+                 * this fails, try using the standard Unicode digit ranges by
+                 * calling UCharacter.digit().  If this also fails, digit will
+                 * have a value outside the range 0..9.
+                 */
+                digit = ch - zero;
+                if (digit < 0 || digit > 9) digit = UCharacter.digit(ch, 10);
+
+                if (digit == 0)
+                {
+                    // Cancel out backup setting (see grouping handler below)
+                    if (strictParse && backup != -1) {
+                        // comma followed by digit, so group before comma is a 
+                        // secondary group.  If there was a group separator
+                        // before that, the group must == the secondary group
+                        // length, else it can be <= the the secondary group
+                        // length.
+                        if ((lastGroup != -1 && backup - lastGroup - 1 != gs2) ||
+                            (lastGroup == -1 && position - oldStart - 1 > gs2)) {
+                            strictFail = true;
+                            break;
+                        }
+                        lastGroup = backup;
+                    }
+                    backup = -1; // Do this BEFORE continue statement below!!!
+                    sawDigit = true;
+
+                    // Handle leading zeros
+                    if (digits.count == 0)
+                    {
+                        if (!sawDecimal) {
+                            if (strictParse && !isExponent) {
+                                // Allow leading zeros in exponents
+                                // Count leading zeros for checking later
+                                if (!strictLeadingZero) leadingZeroPos = position + 1;
+                                strictLeadingZero = true;
+                                ++leadingZeroCount;                                
+                            }
+                            // Ignore leading zeros in integer part of number.
+                            continue;
+                        }
+
+                        // If we have seen the decimal, but no significant digits yet,
+                        // then we account for leading zeros by decrementing the
+                        // digits.decimalAt into negative values.
+                        --digits.decimalAt;
+                    }
+                    else
+                    {
+                        ++digitCount;
+                        digits.append((char)(digit + '0'));
+                    }
+                }
+                else if (digit > 0 && digit <= 9) // [sic] digit==0 handled above
+                {
+                    if (strictParse) {
+                        if (backup != -1) {
+                            if ((lastGroup != -1 && backup - lastGroup - 1 != gs2) ||
+                                (lastGroup == -1 && position - oldStart - 1 > gs2)) {
+                                strictFail = true;
+                                break;
+                            }
+                            lastGroup = backup;
+                        }
+                    }
+
+                    sawDigit = true;
+                    ++digitCount;
+                    digits.append((char)(digit + '0'));
+
+                    // Cancel out backup setting (see grouping handler below)
+                    backup = -1;
+                }
+                else if (!isExponent && decimalSet.contains(ch))
+                {
+                    if (strictParse) {
+                        if (backup != -1 ||
+                            (lastGroup != -1 && position - lastGroup != groupingSize + 1)) {
+                            strictFail = true;
+                            break;
+                        }
+                    }
+                    // If we're only parsing integers, or if we ALREADY saw the
+                    // decimal, then don't parse this one.
+                    if (isParseIntegerOnly() || sawDecimal) break;
+                    digits.decimalAt = digitCount; // Not digits.count!
+                    sawDecimal = true;
+                    
+                    // Once we see a decimal character, we only accept that decimal character from then on.
+                    decimalSet.set(ch,ch);
+                }
+                else if (!isExponent && isGroupingUsed() && groupingSet.contains(ch))
+                {
+                    if (sawDecimal) {
+                        break;
+                    }
+                    if (strictParse) {
+                        if ((!sawDigit || backup != -1)) {
+                            // leading group, or two group separators in a row
+                            strictFail = true;
+                            break;
+                        }
+                    }
+                    // Once we see a grouping character, we only accept that grouping character from then on.
+                    groupingSet.set(ch,ch);
+                    
+                    // Ignore grouping characters, if we are using them, but require
+                    // that they be followed by a digit.  Otherwise we backup and
+                    // reprocess them.
+                    backup = position;
+                }
+                else if (!isExponent && !sawExponent &&
+                         text.regionMatches(position, exponentSep,
+                                            0, exponentSep.length()))
+                {
+                    // Parse sign, if present
+                    boolean negExp = false;
+                    int pos = position + exponentSep.length();
+                    if (pos < text.length()) {
+                        ch = text.charAt(pos);
+                        if (ch == symbols.getPlusSign()) {
+                            ++pos;
+                        } else if (ch == symbols.getMinusSign()) {
+                            ++pos;
+                            negExp = true;
+                        }
+                    }
+
+                    DigitList exponentDigits = new DigitList();
+                    exponentDigits.count = 0;
+                    while (pos < text.length()) {
+                        digit = text.charAt(pos) - zero;
+                        if (digit < 0 || digit > 9) {
+                            /*
+                              Can't parse "[1E0]" when pattern is "0.###E0;[0.###E0]"
+                              Should update reassign the value of 'ch' in the
+                              code:  digit = Character.digit(ch, 10);
+                              [Richard/GCL]
+                            */
+                            digit = UCharacter.digit(text.charAt(pos), 10);
+                        }
+                        if (digit >= 0 && digit <= 9) {
+                            exponentDigits.append((char)(digit + '0'));
+                            ++pos;
+                        } else {
+                            break;
+                        }
+                    }
+                    
+                    if (exponentDigits.count > 0) {
+                        // defer strict parse until we know we have a bona-fide exponent
+                        if (strictParse) {
+                            if (backup != -1 || lastGroup != -1) {
+                                strictFail = true;
+                                break;
+                            }
+                        }
+
+                        // Quick overflow check for exponential part.
+                        // Actual limit check will be done later in this code.
+                        if (exponentDigits.count > 10 /* maximum decimal digits for int */) {
+                            if (negExp) {
+                                // set underflow flag
+                                status[STATUS_UNDERFLOW] = true;
+                            } else {
+                                // set infinite flag
+                                status[STATUS_INFINITE] = true;
+                            }
+                        } else {
+                            exponentDigits.decimalAt = exponentDigits.count;
+                            exponent = exponentDigits.getLong();
+                            if (negExp) {
+                                exponent = -exponent;
+                            }
+                        }
+                        position = pos; // Advance past the exponent
+                        sawExponent = true;
+                    }
+
+                    break; // Whether we fail or succeed, we exit this loop
+                }
+                else break;
+            }
+
+            if (backup != -1) position = backup;
+
+            // If there was no decimal point we have an integer
+            if (!sawDecimal) digits.decimalAt = digitCount; // Not digits.count!            
+            
+            // check for strict parse errors
+            if (strictParse && strictLeadingZero) {
+                if ((leadingZeroCount + digits.decimalAt) > this.getMinimumIntegerDigits()) {
+                    parsePosition.setIndex(oldStart);
+                    parsePosition.setErrorIndex(leadingZeroPos);
+                    return false;
+                }
+            }
+            if (strictParse && !sawDecimal) {
+                if (lastGroup != -1 && position - lastGroup != groupingSize + 1) {
+                    strictFail = true;
+                }
+            }
+            if (strictFail) {
+                // only set with strictParse and a leading zero error
+                // leading zeros are an error with strict parsing except
+                // immediately before nondigit (except group separator 
+                // followed by digit), or end of text.
+                
+                parsePosition.setIndex(oldStart);
+                parsePosition.setErrorIndex(position);
+                return false;
+            }
+
+            // Adjust for exponent, if any
+            exponent += digits.decimalAt;
+            if (exponent < -PARSE_MAX_EXPONENT) {
+                status[STATUS_UNDERFLOW] = true;
+            } else if (exponent > PARSE_MAX_EXPONENT) {
+                status[STATUS_INFINITE] = true;
+            } else {
+                digits.decimalAt = (int)exponent;
+            }
+
+            // If none of the text string was recognized.  For example, parse
+            // "x" with pattern "#0.00" (return index and error index both 0)
+            // parse "$" with pattern "$#0.00". (return index 0 and error index
+            // 1).
+            if (!sawDigit && digitCount == 0) {
+                parsePosition.setIndex(oldStart);
+                parsePosition.setErrorIndex(oldStart);
+                return false;
+            }
+        }
+
+        // Match padding before suffix
+        if (formatWidth > 0 && padPosition == PAD_BEFORE_SUFFIX) {
+            position = skipPadding(text, position);
+        }
+
+        // Match positive and negative suffixes; prefer longest match.
+        if (posMatch >= 0) {
+            posMatch = compareAffix(text, position, false, false, posSuffix, type, currency);
+        }
+        if (negMatch >= 0) {
+            negMatch = compareAffix(text, position, true, false, negSuffix, type, currency);
+        }
+        if (posMatch >= 0 && negMatch >= 0) {
+            if (posMatch > negMatch) {
+                negMatch = -1;
+            } else if (negMatch > posMatch) {
+                posMatch = -1;
+            }  
+        }
+
+        // Fail if neither or both
+        if ((posMatch >= 0) == (negMatch >= 0)) {
+            parsePosition.setErrorIndex(position);
+            return false;
+        }
+
+        position += (posMatch>=0 ? posMatch : negMatch);
+
+        // Match padding after suffix
+        if (formatWidth > 0 && padPosition == PAD_AFTER_SUFFIX) {
+            position = skipPadding(text, position);
+        }
+
+        parsePosition.setIndex(position);
+
+        status[STATUS_POSITIVE] = (posMatch >= 0);
+
+        if (parsePosition.getIndex() == oldStart) {
+            parsePosition.setErrorIndex(position);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Return characters that are used where this decimal is used.
+     * @param decimal
+     * @param strictParse 
+     * @return
+     */
+    private UnicodeSet getSimilarDecimals(char decimal, boolean strictParse) {
+        if (dotEquivalents.contains(decimal)) {
+            return strictParse ? strictDotEquivalents : dotEquivalents;
+        }
+        if (commaEquivalents.contains(decimal)) {
+            return strictParse ? strictCommaEquivalents : commaEquivalents;
+        }
+        // if there is no match, return the character itself
+        return new UnicodeSet().add(decimal);
+    }
+
+    /**
+     * Starting at position, advance past a run of pad characters, if any.
+     * Return the index of the first character after position that is not a pad
+     * character.  Result is >= position.
+     */
+    private final int skipPadding(String text, int position) {
+        while (position < text.length() && text.charAt(position) == pad) {
+            ++position;
+        }
+        return position;
+    }
+
+    /*
+     * Return the length matched by the given affix, or -1 if none.
+     * Runs of white space in the affix, match runs of white space in
+     * the input.  Pattern white space and input white space are
+     * determined differently; see code.
+     * @param text input text
+     * @param pos offset into input at which to begin matching
+     * @param isNegative
+     * @param isPrefix
+     * @param affixPat affix pattern used for currency affix comparison
+     * @param type compare against currency type, LONG_NAME only or not.
+     * @param currency return value for parsed currency, for generic
+     * currency parsing mode, or null for normal parsing. In generic
+     * currency parsing mode, any currency is parsed, not just the
+     * currency that this formatter is set to.
+     * @return length of input that matches, or -1 if match failure
+     */
+    private int compareAffix(String text, int pos, 
+                             boolean isNegative, boolean isPrefix,
+                             String affixPat,
+                             int type,
+                             Currency[] currency) {
+        if (currency != null || currencyChoice != null ||
+            currencySignCount > 0) {
+                return compareComplexAffix(affixPat, text, pos, type, currency);
+        }
+        if (isPrefix) {
+            return compareSimpleAffix(isNegative ? negativePrefix : positivePrefix,
+                                      text, pos);
+        } else {
+            return compareSimpleAffix(isNegative ? negativeSuffix : positiveSuffix,
+                                      text, pos);
+        }
+
+    }
+
+
+
+    /**
+     * Return the length matched by the given affix, or -1 if none.
+     * Runs of white space in the affix, match runs of white space in
+     * the input.  Pattern white space and input white space are
+     * determined differently; see code.
+     * @param affix pattern string, taken as a literal
+     * @param input input text
+     * @param pos offset into input at which to begin matching
+     * @return length of input that matches, or -1 if match failure
+     */
+    private static int compareSimpleAffix(String affix, String input, int pos) {
+        int start = pos;
+        for (int i=0; i<affix.length(); ) {
+            int c = UTF16.charAt(affix, i);
+            int len = UTF16.getCharCount(c);
+            if (UCharacterProperty.isRuleWhiteSpace(c)) {
+                // We may have a pattern like: \u200F \u0020
+                //        and input text like: \u200F \u0020
+                // Note that U+200F and U+0020 are RuleWhiteSpace but only
+                // U+0020 is UWhiteSpace.  So we have to first do a direct
+                // match of the run of RULE whitespace in the pattern,
+                // then match any extra characters.
+                boolean literalMatch = false;
+                while (pos < input.length() &&
+                       UTF16.charAt(input, pos) == c) {
+                    literalMatch = true;
+                    i += len;
+                    pos += len;
+                    if (i == affix.length()) {
+                        break;
+                    }
+                    c = UTF16.charAt(affix, i);
+                    len = UTF16.getCharCount(c);
+                    if (!UCharacterProperty.isRuleWhiteSpace(c)) {
+                        break;
+                    }
+                }
+                
+                // Advance over run in affix
+                i = skipRuleWhiteSpace(affix, i);
+                
+                // Advance over run in input text
+                // Must see at least one white space char in input,
+                // unless we've already matched some characters literally.
+                int s = pos;
+                pos = skipUWhiteSpace(input, pos);
+                if (pos == s && !literalMatch) {
+                    return -1;
+                }
+                // If we skip UWhiteSpace in the input text, we need to skip it in the pattern.
+                // Otherwise, the previous lines may have skipped over text (such as U+00A0) that
+                // is also in the affix.
+                i = skipUWhiteSpace(affix, i);
+            } else {
+                if (pos < input.length() &&
+                    UTF16.charAt(input, pos) == c) {
+                    i += len;
+                    pos += len;
+                } else {
+                    return -1;
+                }
+            }
+        }
+        return pos - start;
+    }
+
+    /**
+     * Skip over a run of zero or more isRuleWhiteSpace() characters at
+     * pos in text.
+     */
+    private static int skipRuleWhiteSpace(String text, int pos) {
+        while (pos < text.length()) {
+            int c = UTF16.charAt(text, pos);
+            if (!UCharacterProperty.isRuleWhiteSpace(c)) {
+                break;
+            }
+            pos += UTF16.getCharCount(c);
+        }
+        return pos;
+    }
+
+    /**
+     * Skip over a run of zero or more isUWhiteSpace() characters at pos
+     * in text.
+     */
+    private static int skipUWhiteSpace(String text, int pos) {
+        while (pos < text.length()) {
+            int c = UTF16.charAt(text, pos);
+            if (!UCharacter.isUWhiteSpace(c)) {
+                break;
+            }
+            pos += UTF16.getCharCount(c);
+        }
+        return pos;
+    }
+
+    /*
+     * Return the length matched by the given affix, or -1 if none.
+     * @param affixPat pattern string
+     * @param text input text
+     * @param pos offset into input at which to begin matching
+     * @param type parse against currency type, LONG_NAME only or not.
+     * @param currency return value for parsed currency, for generic
+     * currency parsing mode, or null for normal parsing. In generic
+     * currency parsing mode, any currency is parsed, not just the
+     * currency that this formatter is set to.
+     * @return position after the matched text, or -1 if match failure
+     */
+    private int compareComplexAffix(String affixPat, String text, int pos,
+                                    int type, Currency[] currency) {
+        int start = pos;
+        for (int i=0; 
+             i < affixPat.length() && pos >= 0; ) {
+            char c = affixPat.charAt(i++);
+            if (c == QUOTE) {
+                for (;;) {
+                    int j = affixPat.indexOf(QUOTE, i);
+                    if (j == i) {
+                        pos = match(text, pos, QUOTE);
+                        i = j+1;
+                        break;
+                    } else if (j > i) {
+                        pos = match(text, pos, affixPat.substring(i, j));
+                        i = j+1;
+                        if (i<affixPat.length() &&
+                            affixPat.charAt(i)==QUOTE) {
+                            pos = match(text, pos, QUOTE);
+                            ++i;
+                            // loop again
+                        } else {
+                            break;
+                        }
+                    } else {
+                        // Unterminated quote; should be caught by apply
+                        // pattern.
+                        throw new RuntimeException();
+                    }
+                }
+                continue;
+            }
+
+            switch (c) {
+            case CURRENCY_SIGN:
+                // since the currency names in choice format is saved
+                // the same way as other currency names, 
+                // do not need to do currency choice parsing here.
+                // the general currency parsing parse against all names,
+                // including names in choice format.
+                //assert(currency != null ||
+                //       (getCurrency() != null && currencyChoice != null));
+                boolean intl = i<affixPat.length() &&
+                    affixPat.charAt(i) == CURRENCY_SIGN;
+                if (intl) {
+                    ++i;
+                }
+                boolean plural = i<affixPat.length() &&
+                    affixPat.charAt(i) == CURRENCY_SIGN;
+                if (plural) {
+                    ++i;
+                    intl = false;
+                }
+                // Parse generic currency -- anything for which we
+                // have a display name, or any 3-letter ISO code.
+                // Try to parse display name for our locale; first
+                // determine our locale.
+                // TODO: use locale in CurrencyPluralInfo
+                ULocale uloc = getLocale(ULocale.VALID_LOCALE);
+                if (uloc == null) {
+                    // applyPattern has been called; use the symbols
+                    uloc = symbols.getLocale(ULocale.VALID_LOCALE);
+                }
+                // Delegate parse of display name => ISO code to Currency
+                ParsePosition ppos = new ParsePosition(pos);
+                // using Currency.parse to handle mixed style parsing.
+                String iso = Currency.parse(uloc, text, type, ppos);
+
+                // If parse succeeds, populate currency[0]
+                if (iso != null) {
+                    if (currency != null) {
+                        currency[0] = Currency.getInstance(iso);
+                    }
+                    pos = ppos.getIndex();
+                } else {
+                    pos = -1;
+                }
+                continue;
+            case PATTERN_PERCENT:
+                c = symbols.getPercent();
+                break;
+            case PATTERN_PER_MILLE:
+                c = symbols.getPerMill();
+                break;
+            case PATTERN_MINUS:
+                c = symbols.getMinusSign();
+                break;
+            }
+            pos = match(text, pos, c);
+            if (UCharacterProperty.isRuleWhiteSpace(c)) {
+                i = skipRuleWhiteSpace(affixPat, i);
+            }
+        }
+
+        return pos - start;
+    }
+
+    /**
+     * Match a single character at text[pos] and return the index of the
+     * next character upon success.  Return -1 on failure.  If
+     * isRuleWhiteSpace(ch) then match a run of white space in text.
+     */
+    static final int match(String text, int pos, int ch) {
+        if (pos >= text.length()) { 
+            return -1; 
+        } 
+        if (UCharacterProperty.isRuleWhiteSpace(ch)) {
+            // Advance over run of white space in input text
+            // Must see at least one white space char in input
+            int s = pos;
+            pos = skipUWhiteSpace(text, pos);
+            if (pos == s) {
+                return -1;
+            }
+            return pos;
+        }
+        return (pos >= 0 && UTF16.charAt(text, pos) == ch) ?
+            (pos + UTF16.getCharCount(ch)) : -1;
+    }
+
+    /**
+     * Match a string at text[pos] and return the index of the next
+     * character upon success.  Return -1 on failure.  Match a run of
+     * white space in str with a run of white space in text.
+     */
+    static final int match(String text, int pos, String str) {
+        for (int i=0; i<str.length() && pos >= 0; ) {
+            int ch = UTF16.charAt(str, i);
+            i += UTF16.getCharCount(ch);
+            pos = match(text, pos, ch);
+            if (UCharacterProperty.isRuleWhiteSpace(ch)) {
+                i = skipRuleWhiteSpace(str, i);
+            }
+        }
+        return pos;
+    }
+
+    /**
+     * Returns a copy of the decimal format symbols used by this format.
+     * @return desired DecimalFormatSymbols
+     * @see DecimalFormatSymbols
+     * @stable ICU 2.0
+     */
+    public DecimalFormatSymbols getDecimalFormatSymbols() {
+        try {
+            // don't allow multiple references
+            return (DecimalFormatSymbols) symbols.clone();
+        } catch (Exception foo) {
+            return null; // should never happen
+        }
+    }
+
+
+    /**
+     * Sets the decimal format symbols used by this format.  The
+     * format uses a copy of the provided symbols.
+     * @param newSymbols desired DecimalFormatSymbols
+     * @see DecimalFormatSymbols
+     * @stable ICU 2.0
+     */
+    public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) {
+        symbols = (DecimalFormatSymbols) newSymbols.clone();
+        setCurrencyForSymbols();
+        expandAffixes(null);
+    }
+
+    /**
+     * Update the currency object to match the symbols.  This method
+     * is used only when the caller has passed in a symbols object
+     * that may not be the default object for its locale.
+     */
+    private void setCurrencyForSymbols() {
+        /*Bug 4212072
+          Update the affix strings according to symbols in order to keep
+          the affix strings up to date.
+          [Richard/GCL]
+        */
+        
+        // With the introduction of the Currency object, the currency
+        // symbols in the DFS object are ignored.  For backward
+        // compatibility, we check any explicitly set DFS object.  If it
+        // is a default symbols object for its locale, we change the
+        // currency object to one for that locale.  If it is custom,
+        // we set the currency to null.
+        DecimalFormatSymbols def =
+            new DecimalFormatSymbols(symbols.getLocale());
+        
+        if (symbols.getCurrencySymbol().equals(
+                def.getCurrencySymbol()) &&
+            symbols.getInternationalCurrencySymbol().equals(
+                def.getInternationalCurrencySymbol())) {
+            setCurrency(Currency.getInstance(symbols.getLocale()));
+        } else {
+            setCurrency(null);
+        }
+    }
+
+    /**
+     * Get the positive prefix.
+     * <P>Examples: +123, $123, sFr123
+     * @stable ICU 2.0
+     */
+    public String getPositivePrefix () {
+        return positivePrefix;
+    }
+
+    /**
+     * Set the positive prefix.
+     * <P>Examples: +123, $123, sFr123
+     * @stable ICU 2.0
+     */
+    public void setPositivePrefix (String newValue) {
+        positivePrefix = newValue;
+        posPrefixPattern = null;
+    }
+
+    /**
+     * Get the negative prefix.
+     * <P>Examples: -123, ($123) (with negative suffix), sFr-123
+     * @stable ICU 2.0
+     */
+    public String getNegativePrefix () {
+        return negativePrefix;
+    }
+
+    /**
+     * Set the negative prefix.
+     * <P>Examples: -123, ($123) (with negative suffix), sFr-123
+     * @stable ICU 2.0
+     */
+    public void setNegativePrefix (String newValue) {
+        negativePrefix = newValue;
+        negPrefixPattern = null;
+    }
+
+    /**
+     * Get the positive suffix.
+     * <P>Example: 123%
+     * @stable ICU 2.0
+     */
+    public String getPositiveSuffix () {
+        return positiveSuffix;
+    }
+
+    /**
+     * Set the positive suffix.
+     * <P>Example: 123%
+     * @stable ICU 2.0
+     */
+    public void setPositiveSuffix (String newValue) {
+        positiveSuffix = newValue;
+        posSuffixPattern = null;
+    }
+
+    /**
+     * Get the negative suffix.
+     * <P>Examples: -123%, ($123) (with positive suffixes)
+     * @stable ICU 2.0
+     */
+    public String getNegativeSuffix () {
+        return negativeSuffix;
+    }
+
+    /**
+     * Set the positive suffix.
+     * <P>Examples: 123%
+     * @stable ICU 2.0
+     */
+    public void setNegativeSuffix (String newValue) {
+        negativeSuffix = newValue;
+        negSuffixPattern = null;
+    }
+
+    /**
+     * Get the multiplier for use in percent, permill, etc.
+     * For a percentage, set the suffixes to have "%" and the multiplier to be 100.
+     * (For Arabic, use arabic percent symbol).
+     * For a permill, set the suffixes to have "\u2031" and the multiplier to be 1000.
+     * <P>Examples: with 100, 1.23 -> "123", and "123" -> 1.23
+     * @stable ICU 2.0
+     */
+    public int getMultiplier () {
+        return multiplier;
+    }
+
+    /**
+     * Set the multiplier for use in percent, permill, etc.
+     * For a percentage, set the suffixes to have "%" and the multiplier to be 100.
+     * (For Arabic, use arabic percent symbol).
+     * For a permill, set the suffixes to have "\u2031" and the multiplier to be 1000.
+     * <P>Examples: with 100, 1.23 -> "123", and "123" -> 1.23
+     * @stable ICU 2.0
+     */
+    public void setMultiplier (int newValue) {
+        if (newValue == 0) {
+            throw new IllegalArgumentException("Bad multiplier: " + newValue);
+        }
+        multiplier = newValue;
+    }
+    
+    // [NEW]
+    /**
+     * Get the rounding increment.
+     * @return A positive rounding increment, or <code>null</code> if rounding
+     * is not in effect.
+     * @see #setRoundingIncrement
+     * @see #getRoundingMode
+     * @see #setRoundingMode
+     * @stable ICU 2.0
+     */
+//#if defined(FOUNDATION10) || defined(ECLIPSE_FRAGMENT)
+//##    public BigDecimal getRoundingIncrement() {
+//##        if (roundingIncrementICU == null) return null;
+//##        return new BigDecimal(roundingIncrementICU.toString());
+//##    }
+//#else
+    public java.math.BigDecimal getRoundingIncrement() {
+        if (roundingIncrementICU == null) return null;
+        return roundingIncrementICU.toBigDecimal();
+    }
+//#endif
+    
+//#if defined(FOUNDATION10)
+//#else
+    // [NEW]
+    /**
+     * Set the rounding increment.  This method also controls whether
+     * rounding is enabled.
+     * @param newValue A positive rounding increment, or <code>null</code> or
+     * <code>BigDecimal(0.0)</code> to disable rounding.
+     * @exception IllegalArgumentException if <code>newValue</code> is < 0.0
+     * @see #getRoundingIncrement
+     * @see #getRoundingMode
+     * @see #setRoundingMode
+     * @stable ICU 2.0
+     */
+    public void setRoundingIncrement(java.math.BigDecimal newValue) {
+        if (newValue == null) {
+            setRoundingIncrement((BigDecimal)null);
+        } else {
+            setRoundingIncrement(new BigDecimal(newValue));
+        }
+    }
+//#endif
+    
+    // [NEW]
+    /**
+     * Set the rounding increment.  This method also controls whether
+     * rounding is enabled.
+     * @param newValue A positive rounding increment, or <code>null</code> or
+     * <code>BigDecimal(0.0)</code> to disable rounding.
+     * @exception IllegalArgumentException if <code>newValue</code> is < 0.0
+     * @see #getRoundingIncrement
+     * @see #getRoundingMode
+     * @see #setRoundingMode
+     * @stable ICU 3.6
+     */
+    public void setRoundingIncrement(BigDecimal newValue) {
+        int i = newValue == null
+            ? 0 : newValue.compareTo(BigDecimal.ZERO);
+        if (i < 0) {
+            throw new IllegalArgumentException("Illegal rounding increment");
+        }
+        if (i == 0) {
+            setInternalRoundingIncrement(null);
+        } else {
+            setInternalRoundingIncrement(newValue);
+        }
+        setRoundingDouble();
+    }
+
+    // [NEW]
+    /**
+     * Set the rounding increment.  This method also controls whether
+     * rounding is enabled.
+     * @param newValue A positive rounding increment, or 0.0 to disable
+     * rounding.
+     * @exception IllegalArgumentException if <code>newValue</code> is < 0.0
+     * @see #getRoundingIncrement
+     * @see #getRoundingMode
+     * @see #setRoundingMode
+     * @stable ICU 2.0
+     */
+    public void setRoundingIncrement(double newValue) {
+        if (newValue < 0.0) {
+            throw new IllegalArgumentException("Illegal rounding increment");
+        }
+        roundingDouble = newValue;
+        roundingDoubleReciprocal = 0.0d;
+        if (newValue == 0.0d) {
+            setRoundingIncrement((BigDecimal)null);
+        } else {
+            roundingDouble = newValue;
+            if (roundingDouble < 1.0d) {
+                double rawRoundedReciprocal = 1.0d/roundingDouble;
+                setRoundingDoubleReciprocal(rawRoundedReciprocal);
+            }
+            setInternalRoundingIncrement(new BigDecimal(newValue));
+        }
+    }
+
+
+    private void setRoundingDoubleReciprocal(double rawRoundedReciprocal) {
+        roundingDoubleReciprocal = Math.rint(rawRoundedReciprocal);
+        if (Math.abs(rawRoundedReciprocal - roundingDoubleReciprocal) > roundingIncrementEpsilon) {
+            roundingDoubleReciprocal = 0.0d;
+        }
+    }
+    
+    static final double roundingIncrementEpsilon = 0.000000001;
+    
+    /**
+     * Get the rounding mode.
+     * @return A rounding mode, between <code>BigDecimal.ROUND_UP</code>
+     * and <code>BigDecimal.ROUND_UNNECESSARY</code>.
+     * @see #setRoundingIncrement
+     * @see #getRoundingIncrement
+     * @see #setRoundingMode
+     * @see java.math.BigDecimal
+     * @stable ICU 2.0
+     */
+    public int getRoundingMode() {
+        return roundingMode;
+    }
+
+    /**
+     * Set the rounding mode.  This has no effect unless the rounding
+     * increment is greater than zero.
+     * @param roundingMode A rounding mode, between
+     * <code>BigDecimal.ROUND_UP</code> and
+     * <code>BigDecimal.ROUND_UNNECESSARY</code>.
+     * @exception IllegalArgumentException if <code>roundingMode</code>
+     * is unrecognized.
+     * @see #setRoundingIncrement
+     * @see #getRoundingIncrement
+     * @see #getRoundingMode
+     * @see java.math.BigDecimal
+     * @stable ICU 2.0
+     */
+    public void setRoundingMode(int roundingMode) {
+        if (roundingMode < BigDecimal.ROUND_UP
+            || roundingMode > BigDecimal.ROUND_UNNECESSARY) {
+            throw new IllegalArgumentException("Invalid rounding mode: "
+                                               + roundingMode);
+        }
+
+        this.roundingMode = roundingMode;
+
+        if (getRoundingIncrement() == null) {
+            setRoundingIncrement(Math.pow(10.0,(double)-getMaximumFractionDigits()));
+        }
+    }
+
+    // [NEW]
+    /**
+     * Get the width to which the output of <code>format()</code> is padded.
+     * The width is counted in 16-bit code units.
+     * @return the format width, or zero if no padding is in effect
+     * @see #setFormatWidth
+     * @see #getPadCharacter
+     * @see #setPadCharacter
+     * @see #getPadPosition
+     * @see #setPadPosition
+     * @stable ICU 2.0
+     */
+    public int getFormatWidth() {
+        return formatWidth;
+    }
+
+    // [NEW]
+    /**
+     * Set the width to which the output of <code>format()</code> is padded.
+     * The width is counted in 16-bit code units.
+     * This method also controls whether padding is enabled.
+     * @param width the width to which to pad the result of
+     * <code>format()</code>, or zero to disable padding
+     * @exception IllegalArgumentException if <code>width</code> is < 0
+     * @see #getFormatWidth
+     * @see #getPadCharacter
+     * @see #setPadCharacter
+     * @see #getPadPosition
+     * @see #setPadPosition
+     * @stable ICU 2.0
+     */
+    public void setFormatWidth(int width) {
+        if (width < 0) {
+            throw new IllegalArgumentException("Illegal format width");
+        }
+        formatWidth = width;
+    }
+
+    // [NEW]
+    /**
+     * Get the character used to pad to the format width.  The default is ' '.
+     * @return the pad character
+     * @see #setFormatWidth
+     * @see #getFormatWidth
+     * @see #setPadCharacter
+     * @see #getPadPosition
+     * @see #setPadPosition
+     * @stable ICU 2.0
+     */
+    public char getPadCharacter() {
+        return pad;
+    }
+
+    // [NEW]
+    /**
+     * Set the character used to pad to the format width.  If padding
+     * is not enabled, then this will take effect if padding is later
+     * enabled.
+     * @param padChar the pad character
+     * @see #setFormatWidth
+     * @see #getFormatWidth
+     * @see #getPadCharacter
+     * @see #getPadPosition
+     * @see #setPadPosition
+     * @stable ICU 2.0
+     */
+    public void setPadCharacter(char padChar) {
+        pad = padChar;
+    }
+
+    // [NEW]
+    /**
+     * Get the position at which padding will take place.  This is the location
+     * at which padding will be inserted if the result of <code>format()</code>
+     * is shorter than the format width.
+     * @return the pad position, one of <code>PAD_BEFORE_PREFIX</code>,
+     * <code>PAD_AFTER_PREFIX</code>, <code>PAD_BEFORE_SUFFIX</code>, or
+     * <code>PAD_AFTER_SUFFIX</code>.
+     * @see #setFormatWidth
+     * @see #getFormatWidth
+     * @see #setPadCharacter
+     * @see #getPadCharacter
+     * @see #setPadPosition
+     * @see #PAD_BEFORE_PREFIX
+     * @see #PAD_AFTER_PREFIX
+     * @see #PAD_BEFORE_SUFFIX
+     * @see #PAD_AFTER_SUFFIX
+     * @stable ICU 2.0
+     */
+    public int getPadPosition() {
+        return padPosition;
+    }
+
+    // [NEW]
+    /**
+     * Set the position at which padding will take place.  This is the location
+     * at which padding will be inserted if the result of <code>format()</code>
+     * is shorter than the format width.  This has no effect unless padding is
+     * enabled.
+     * @param padPos the pad position, one of <code>PAD_BEFORE_PREFIX</code>,
+     * <code>PAD_AFTER_PREFIX</code>, <code>PAD_BEFORE_SUFFIX</code>, or
+     * <code>PAD_AFTER_SUFFIX</code>.
+     * @exception IllegalArgumentException if the pad position in
+     * unrecognized
+     * @see #setFormatWidth
+     * @see #getFormatWidth
+     * @see #setPadCharacter
+     * @see #getPadCharacter
+     * @see #getPadPosition
+     * @see #PAD_BEFORE_PREFIX
+     * @see #PAD_AFTER_PREFIX
+     * @see #PAD_BEFORE_SUFFIX
+     * @see #PAD_AFTER_SUFFIX
+     * @stable ICU 2.0
+     */
+    public void setPadPosition(int padPos) {
+        if (padPos < PAD_BEFORE_PREFIX || padPos > PAD_AFTER_SUFFIX) {
+            throw new IllegalArgumentException("Illegal pad position");
+        }
+        padPosition = padPos;
+    }
+
+    // [NEW]
+    /**
+     * Return whether or not scientific notation is used.
+     * @return true if this object formats and parses scientific notation
+     * @see #setScientificNotation
+     * @see #getMinimumExponentDigits
+     * @see #setMinimumExponentDigits
+     * @see #isExponentSignAlwaysShown
+     * @see #setExponentSignAlwaysShown
+     * @stable ICU 2.0
+     */
+    public boolean isScientificNotation() {
+        return useExponentialNotation;
+    }
+
+    // [NEW]
+    /**
+     * Set whether or not scientific notation is used.  When scientific notation
+     * is used, the effective maximum number of integer digits is <= 8.  If the
+     * maximum number of integer digits is set to more than 8, the effective
+     * maximum will be 1.  This allows this call to generate a 'default' scientific
+     * number format without additional changes.
+     * @param useScientific true if this object formats and parses scientific
+     * notation
+     * @see #isScientificNotation
+     * @see #getMinimumExponentDigits
+     * @see #setMinimumExponentDigits
+     * @see #isExponentSignAlwaysShown
+     * @see #setExponentSignAlwaysShown
+     * @stable ICU 2.0
+     */
+    public void setScientificNotation(boolean useScientific) {
+        useExponentialNotation = useScientific;
+    }
+
+    // [NEW]
+    /**
+     * Return the minimum exponent digits that will be shown.
+     * @return the minimum exponent digits that will be shown
+     * @see #setScientificNotation
+     * @see #isScientificNotation
+     * @see #setMinimumExponentDigits
+     * @see #isExponentSignAlwaysShown
+     * @see #setExponentSignAlwaysShown
+     * @stable ICU 2.0
+     */
+    public byte getMinimumExponentDigits() {
+        return minExponentDigits;
+    }
+    
+    // [NEW]
+    /**
+     * Set the minimum exponent digits that will be shown.  This has no
+     * effect unless scientific notation is in use.
+     * @param minExpDig a value >= 1 indicating the fewest exponent digits
+     * that will be shown
+     * @exception IllegalArgumentException if <code>minExpDig</code> < 1
+     * @see #setScientificNotation
+     * @see #isScientificNotation
+     * @see #getMinimumExponentDigits
+     * @see #isExponentSignAlwaysShown
+     * @see #setExponentSignAlwaysShown
+     * @stable ICU 2.0
+     */
+    public void setMinimumExponentDigits(byte minExpDig) {
+        if (minExpDig < 1) {
+            throw new IllegalArgumentException("Exponent digits must be >= 1");
+        }
+        minExponentDigits = minExpDig;
+    }
+
+    // [NEW]
+    /**
+     * Return whether the exponent sign is always shown.
+     * @return true if the exponent is always prefixed with either the
+     * localized minus sign or the localized plus sign, false if only negative
+     * exponents are prefixed with the localized minus sign.
+     * @see #setScientificNotation
+     * @see #isScientificNotation
+     * @see #setMinimumExponentDigits
+     * @see #getMinimumExponentDigits
+     * @see #setExponentSignAlwaysShown
+     * @stable ICU 2.0
+     */
+    public boolean isExponentSignAlwaysShown() {
+        return exponentSignAlwaysShown;
+    }
+
+    // [NEW]
+    /**
+     * Set whether the exponent sign is always shown.  This has no effect
+     * unless scientific notation is in use.
+     * @param expSignAlways true if the exponent is always prefixed with either
+     * the localized minus sign or the localized plus sign, false if only
+     * negative exponents are prefixed with the localized minus sign.
+     * @see #setScientificNotation
+     * @see #isScientificNotation
+     * @see #setMinimumExponentDigits
+     * @see #getMinimumExponentDigits
+     * @see #isExponentSignAlwaysShown
+     * @stable ICU 2.0
+     */
+    public void setExponentSignAlwaysShown(boolean expSignAlways) {
+        exponentSignAlwaysShown = expSignAlways;
+    }
+
+    /**
+     * Return the grouping size. Grouping size is the number of digits between
+     * grouping separators in the integer portion of a number.  For example,
+     * in the number "123,456.78", the grouping size is 3.
+     * @see #setGroupingSize
+     * @see NumberFormat#isGroupingUsed
+     * @see DecimalFormatSymbols#getGroupingSeparator
+     * @stable ICU 2.0
+     */
+    public int getGroupingSize () {
+        return groupingSize;
+    }
+
+    /**
+     * Set the grouping size. Grouping size is the number of digits between
+     * grouping separators in the integer portion of a number.  For example,
+     * in the number "123,456.78", the grouping size is 3.
+     * @see #getGroupingSize
+     * @see NumberFormat#setGroupingUsed
+     * @see DecimalFormatSymbols#setGroupingSeparator
+     * @stable ICU 2.0
+     */
+    public void setGroupingSize (int newValue) {
+        groupingSize = (byte)newValue;
+    }
+
+    // [NEW]
+    /**
+     * Return the secondary grouping size. In some locales one
+     * grouping interval is used for the least significant integer
+     * digits (the primary grouping size), and another is used for all
+     * others (the secondary grouping size).  A formatter supporting a
+     * secondary grouping size will return a positive integer unequal
+     * to the primary grouping size returned by
+     * <code>getGroupingSize()</code>.  For example, if the primary
+     * grouping size is 4, and the secondary grouping size is 2, then
+     * the number 123456789 formats as "1,23,45,6789", and the pattern
+     * appears as "#,##,###0".
+     * @return the secondary grouping size, or a value less than
+     * one if there is none
+     * @see #setSecondaryGroupingSize
+     * @see NumberFormat#isGroupingUsed
+     * @see DecimalFormatSymbols#getGroupingSeparator
+     * @stable ICU 2.0
+     */
+    public int getSecondaryGroupingSize () {
+        return groupingSize2;
+    }
+
+    // [NEW]
+    /**
+     * Set the secondary grouping size. If set to a value less than 1,
+     * then secondary grouping is turned off, and the primary grouping
+     * size is used for all intervals, not just the least significant.
+     * @see #getSecondaryGroupingSize
+     * @see NumberFormat#setGroupingUsed
+     * @see DecimalFormatSymbols#setGroupingSeparator
+     * @stable ICU 2.0
+     */
+    public void setSecondaryGroupingSize (int newValue) {
+        groupingSize2 = (byte)newValue;
+    }
+
+    // [NEW]
+    /**
+     * Returns the MathContext
+     * used by this format. 
+     * @return desired MathContext
+     * @see #mathContext
+     * @see #getMathContext
+     * @draft ICU 4.2
+     * @provisional This API might change or be removed in a future release.
+     */
+    public MathContext getMathContextICU() {
+        return mathContext;
+    }
+
+//#if defined(FOUNDATION10) || defined(J2SE13) || defined(J2SE14) || defined(ECLIPSE_FRAGMENT)
+//#else
+    // [NEW]
+    /**
+     * Returns the MathContext
+     * used by this format. 
+     * @return desired MathContext
+     * @see #mathContext
+     * @see #getMathContext
+     * @draft ICU 4.2
+     * @provisional This API might change or be removed in a future release.
+     */
+    public java.math.MathContext getMathContext()
+    {
+        try
+        {
+            // don't allow multiple references
+            return mathContext == null ?
+                   null :
+                   new java.math.MathContext(mathContext.getDigits(),
+                                             java.math.RoundingMode.valueOf(mathContext.getRoundingMode()));
+        }
+        catch (Exception foo)
+        {
+            return null; // should never happen
+        }
+    }
+//#endif
+
+    // [NEW]
+    /**
+     * Sets the MathContext used by this format.
+     * @param newValue desired MathContext
+     * @see #mathContext
+     * @see #getMathContext
+     * @draft ICU 4.2
+     * @provisional This API might change or be removed in a future release.
+     */
+    public void setMathContextICU(MathContext newValue) {
+        mathContext = newValue;
+    }
+
+//#if defined(FOUNDATION10) || defined(J2SE13) || defined(J2SE14) || defined(ECLIPSE_FRAGMENT)
+//#else
+    // [NEW]
+    /**
+     * Sets the MathContext used by this format.
+     * @param newValue desired MathContext
+     * @see #mathContext
+     * @see #getMathContext
+     * @draft ICU 4.2
+     * @provisional This API might change or be removed in a future release.
+     */
+    public void setMathContext(java.math.MathContext newValue)
+    {
+        mathContext = new MathContext(newValue.getPrecision(),
+                                      MathContext.SCIENTIFIC,
+                                      false,
+                                      (newValue.getRoundingMode()).ordinal()
+                                      );
+    }
+//#endif
+
+    /**
+     * Allows you to get the behavior of the decimal separator with integers.
+     * (The decimal separator will always appear with decimals.)
+     * <P>Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345
+     * @stable ICU 2.0
+     */
+    public boolean isDecimalSeparatorAlwaysShown() {
+        return decimalSeparatorAlwaysShown;
+    }
+
+    /**
+     * Allows you to set the behavior of the decimal separator with integers.
+     * (The decimal separator will always appear with decimals.)
+     *
+     * <p>This only affects formatting, and only where
+     * there might be no digits after the decimal point, e.g.,
+     * if true,  3456.00 -> "3,456."
+     * if false, 3456.00 -> "3456"
+     * This is independent of parsing.  If you want parsing to stop at the decimal
+     * point, use setParseIntegerOnly.
+     *
+     * <P>Example: Decimal ON: 12345 -> 12345.; OFF: 12345 -> 12345
+     * @stable ICU 2.0
+     */
+    public void setDecimalSeparatorAlwaysShown(boolean newValue) {
+        decimalSeparatorAlwaysShown = newValue;
+    }
+
+    /**
+     * Returns a copy of the CurrencyPluralInfo 
+     * used by this format. 
+     * It might return null if the decimal format is not a plural type 
+     * currency decimal format.
+     * Plural type currency decimal format means either
+     * the pattern in the decimal format contains 3 currency signs,
+     * or the decimal format is initialized with PLURALCURRENCYSTYLE.
+     * @return desired CurrencyPluralInfo
+     * @see CurrencyPluralInfo
+     * @draft ICU 4.2
+     * @provisional This API might change or be removed in a future release.
+     */
+    public CurrencyPluralInfo getCurrencyPluralInfo() {
+        try {
+            // don't allow multiple references
+            return currencyPluralInfo == null ? 
+                   null :
+                   (CurrencyPluralInfo) currencyPluralInfo.clone();
+        } catch (Exception foo) {
+            return null; // should never happen
+        }
+    }
+
+
+    /**
+     * Sets the CurrencyPluralInfo used by this format.  The
+     * format uses a copy of the provided information.
+     * @param newInfo desired CurrencyPluralInfo
+     * @see CurrencyPluralInfo
+     * @draft ICU 4.2
+     * @provisional This API might change or be removed in a future release.
+     */
+    public void setCurrencyPluralInfo(CurrencyPluralInfo newInfo) {
+        currencyPluralInfo = (CurrencyPluralInfo) newInfo.clone();
+        isReadyForParsing = false;
+    }
+
+    /**
+     * Standard override; no change in semantics.
+     * @stable ICU 2.0
+     */
+    public Object clone() {
+        try {
+            DecimalFormat other = (DecimalFormat) super.clone();
+            other.symbols = (DecimalFormatSymbols) symbols.clone();
+            other.digitList = new DigitList(); // fix for JB#5358
+            if (currencyPluralInfo != null) {
+                other.currencyPluralInfo = (CurrencyPluralInfo)currencyPluralInfo.clone();
+            }
+            /*
+             * TODO: We need to figure out whether we share a single copy
+             * of DigitList by multiple cloned copies.  format/subformat
+             * are designed to use a single instance, but parse/subparse
+             * implementation is not. 
+             */
+            return other;
+        } catch (Exception e) {
+            throw new IllegalStateException();
+        }
+    }
+
+    /**
+     * Overrides equals
+     * @stable ICU 2.0
+     */
+    public boolean equals(Object obj)
+    {
+        if (obj == null) return false;
+        if (!super.equals(obj)) return false; // super does class check
+
+        DecimalFormat other = (DecimalFormat) obj;
+        /* Add the comparison of the four new added fields ,they are
+         * posPrefixPattern, posSuffixPattern, negPrefixPattern, negSuffixPattern.
+         * [Richard/GCL]
+         */
+        // following are added to accomodate changes for currency plural format.
+        return currencySignCount == other.currencySignCount
+            && (style != NumberFormat.PLURALCURRENCYSTYLE ||
+                   equals(posPrefixPattern, other.posPrefixPattern)
+                   && equals(posSuffixPattern, other.posSuffixPattern)
+                   && equals(negPrefixPattern, other.negPrefixPattern)
+                   && equals(negSuffixPattern, other.negSuffixPattern))
+            && multiplier == other.multiplier
+            && groupingSize == other.groupingSize
+            && groupingSize2 == other.groupingSize2
+            && decimalSeparatorAlwaysShown == other.decimalSeparatorAlwaysShown
+            && useExponentialNotation == other.useExponentialNotation
+            && (!useExponentialNotation ||
+                minExponentDigits == other.minExponentDigits)
+            && useSignificantDigits == other.useSignificantDigits
+            && (!useSignificantDigits ||
+                minSignificantDigits == other.minSignificantDigits &&
+                maxSignificantDigits == other.maxSignificantDigits)
+            && symbols.equals(other.symbols) 
+            && Utility.objectEquals(currencyPluralInfo, other.currencyPluralInfo);
+    }
+
+    //method to unquote the strings and compare
+    private boolean equals(String pat1, String pat2){
+        if (pat1 == null || pat2 == null) {
+            return (pat1 == null && pat2 == null);
+        }
+        //fast path
+        if(pat1.equals(pat2)){
+            return true;
+        }
+        return unquote(pat1).equals(unquote(pat2));
+    }
+    private String unquote(String pat){
+        StringBuffer buf = new StringBuffer(pat.length());
+        int i=0;
+        while(i<pat.length()){
+            char ch = pat.charAt(i++);
+            if(ch!=QUOTE){
+                buf.append(ch);
+            }
+        }
+        return buf.toString();
+    }
+//      protected void handleToString(StringBuffer buf) {
+//          buf.append("\nposPrefixPattern: '" + posPrefixPattern + "'\n");
+//          buf.append("positivePrefix: '" + positivePrefix + "'\n");
+//          buf.append("posSuffixPattern: '" + posSuffixPattern + "'\n");
+//          buf.append("positiveSuffix: '" + positiveSuffix + "'\n");
+//          buf.append("negPrefixPattern: '" + com.ibm.icu.impl.Utility.format1ForSource(negPrefixPattern) + "'\n");
+//          buf.append("negativePrefix: '" + com.ibm.icu.impl.Utility.format1ForSource(negativePrefix) + "'\n");
+//          buf.append("negSuffixPattern: '" + negSuffixPattern + "'\n");
+//          buf.append("negativeSuffix: '" + negativeSuffix + "'\n");
+//          buf.append("multiplier: '" + multiplier + "'\n");
+//          buf.append("groupingSize: '" + groupingSize + "'\n");
+//          buf.append("groupingSize2: '" + groupingSize2 + "'\n");
+//          buf.append("decimalSeparatorAlwaysShown: '" + decimalSeparatorAlwaysShown + "'\n");
+//          buf.append("useExponentialNotation: '" + useExponentialNotation + "'\n");
+//          buf.append("minExponentDigits: '" + minExponentDigits + "'\n");
+//          buf.append("useSignificantDigits: '" + useSignificantDigits + "'\n");
+//          buf.append("minSignificantDigits: '" + minSignificantDigits + "'\n");
+//          buf.append("maxSignificantDigits: '" + maxSignificantDigits + "'\n");           
+//          buf.append("symbols: '" + symbols + "'");
+//      }
+
+    /**
+     * Overrides hashCode
+     * @stable ICU 2.0
+     */
+    public int hashCode() {
+        return super.hashCode() * 37 + positivePrefix.hashCode();
+        // just enough fields for a reasonable distribution
+    }
+
+    /**
+     * Synthesizes a pattern string that represents the current state
+     * of this Format object.
+     * @see #applyPattern
+     * @stable ICU 2.0
+     */
+    public String toPattern() {
+        if (style == NumberFormat.PLURALCURRENCYSTYLE) {
+            // the prefix or suffix pattern might not be defined yet,
+            // so they can not be synthesized,
+            // instead, get them directly.
+            // but it might not be the actual pattern used in formatting.
+            // the actual pattern used in formatting depends on the 
+            // formatted number's plural count.
+            return formatPattern;
+        }
+        return toPattern( false );
+    }
+
+    /**
+     * Synthesizes a localized pattern string that represents the current
+     * state of this Format object.
+     * @see #applyPattern
+     * @stable ICU 2.0
+     */
+    public String toLocalizedPattern() {
+        if (style == NumberFormat.PLURALCURRENCYSTYLE) {
+            return formatPattern;
+        }
+        return toPattern( true );
+    }
+
+    /**
+     * Expand the affix pattern strings into the expanded affix strings.  If any
+     * affix pattern string is null, do not expand it.  This method should be
+     * called any time the symbols or the affix patterns change in order to keep
+     * the expanded affix strings up to date.
+     * This method also will be called before formatting if format currency
+     * plural names, since the plural name is not a static one, it is 
+     * based on the currency plural count, the affix will be known only
+     * after the currency plural count is know. 
+     * In which case, the parameter
+     * 'pluralCount' will be a non-null currency plural count.
+     * In all other cases, the 'pluralCount' is null, which means 
+     * it is not needed.
+     */
+    //Bug 4212072 [Richard/GCL]
+    private void expandAffixes(String pluralCount) {
+        // expandAffix() will set currencyChoice to a non-null value if
+        // appropriate AND if it is null.
+        currencyChoice = null;
+
+        // Reuse one StringBuffer for better performance
+        StringBuffer buffer = new StringBuffer();
+        if (posPrefixPattern != null) {
+            expandAffix(posPrefixPattern, pluralCount, buffer, false);
+            positivePrefix = buffer.toString();
+        }
+        if (posSuffixPattern != null) {
+            expandAffix(posSuffixPattern, pluralCount, buffer, false);
+            positiveSuffix = buffer.toString();
+        }
+        if (negPrefixPattern != null) {
+            expandAffix(negPrefixPattern, pluralCount, buffer, false);
+            negativePrefix = buffer.toString();
+        }
+        if (negSuffixPattern != null) {
+            expandAffix(negSuffixPattern, pluralCount, buffer, false);
+            negativeSuffix = buffer.toString();
+        }
+    }
+
+    /**
+     * Expand an affix pattern into an affix string.  All characters in
+     * the pattern are literal unless bracketed by QUOTEs.  The
+     * following characters outside QUOTE are recognized:
+     * PATTERN_PERCENT, PATTERN_PER_MILLE, PATTERN_MINUS, and
+     * CURRENCY_SIGN.  If CURRENCY_SIGN is doubled, it is interpreted as
+     * an international currency sign.  If CURRENCY_SIGN is tripled,
+     * it is interpreted as currency plural long names, such as "US Dollars".
+     * Any other character outside
+     * QUOTE represents itself.  Quoted text must be well-formed.
+     *
+     * This method is used in two distinct ways.  First, it is used to expand
+     * the stored affix patterns into actual affixes.  For this usage, doFormat
+     * must be false.  Second, it is used to expand the stored affix patterns
+     * given a specific number (doFormat == true), for those rare cases in
+     * which a currency format references a ChoiceFormat (e.g., en_IN display
+     * name for INR).  The number itself is taken from digitList.
+     *
+     * When used in the first way, this method has a side effect: It sets
+     * currencyChoice to a ChoiceFormat object, if the currency's display name
+     * in this locale is a ChoiceFormat pattern (very rare).  It only does this
+     * if currencyChoice is null to start with.
+     *
+     * @param pattern the non-null, possibly empty pattern
+     * @param pluralCount the plural count. It is only used for currency
+     *                    plural format. In which case, it is the plural
+     *                    count of the currency amount. For example,
+     *                    in en_US, it is the singular "one", or the plural
+     *                    "other". For all other cases, it is null, and
+     *                    is not being used.
+     * @param buffer a scratch StringBuffer; its contents will be lost
+     * @param doFormat if false, then the pattern will be expanded, and if a
+     * currency symbol is encountered that expands to a ChoiceFormat, the
+     * currencyChoice member variable will be initialized if it is null.  If
+     * doFormat is true, then it is assumed that the currencyChoice has been
+     * created, and it will be used to format the value in digitList.
+     * @return the expanded equivalent of pattern
+     */
+    //Bug 4212072 [Richard/GCL]
+    private void expandAffix(String pattern, 
+                             String pluralCount, 
+                             StringBuffer buffer,
+                             boolean doFormat) {
+        buffer.setLength(0);
+        for (int i=0; i<pattern.length(); ) {
+            char c = pattern.charAt(i++);
+            if (c == QUOTE) {
+                for (;;) {
+                    int j = pattern.indexOf(QUOTE, i);
+                    if (j == i) {
+                        buffer.append(QUOTE);
+                        i = j+1;
+                        break;
+                    } else if (j > i) {
+                        buffer.append(pattern.substring(i, j));
+                        i = j+1;
+                        if (i<pattern.length() &&
+                            pattern.charAt(i)==QUOTE) {
+                            buffer.append(QUOTE);
+                            ++i;
+                            // loop again
+                        } else {
+                            break;
+                        }
+                    } else {
+                        // Unterminated quote; should be caught by apply
+                        // pattern.
+                        throw new RuntimeException();
+                    }
+                }
+                continue;
+            }
+
+            switch (c) {
+            case CURRENCY_SIGN:
+                // As of ICU 2.2 we use the currency object, and
+                // ignore the currency symbols in the DFS, unless
+                // we have a null currency object.  This occurs if
+                // resurrecting a pre-2.2 object or if the user
+                // sets a custom DFS.
+                boolean intl = i<pattern.length() &&
+                    pattern.charAt(i) == CURRENCY_SIGN;
+                boolean plural = false;
+                if (intl) {
+                    ++i;
+                    if (i<pattern.length() &&
+                        pattern.charAt(i) == CURRENCY_SIGN) {
+                        plural = true;
+                        intl = false;
+                        ++i;
+                    }
+                }
+                String s = null;
+                Currency currency = getCurrency();
+                if (currency != null) {
+                    // plural name is only needed when pluralCount != null,
+                    // which means when formatting currency plural names.
+                    // For other cases, pluralCount == null,
+                    // and plural names are not needed.
+                    if (plural && pluralCount != null) {
+                        boolean isChoiceFormat[] = new boolean[1];
+                        s = currency.getName(symbols.getULocale(), 
+                                             Currency.PLURAL_LONG_NAME, 
+                                             pluralCount, 
+                                             isChoiceFormat);
+                    }
+                    else if (!intl) {
+                        boolean isChoiceFormat[] = new boolean[1];
+                        s = currency.getName(symbols.getULocale(),
+                                             Currency.SYMBOL_NAME,
+                                             isChoiceFormat);
+                        if (isChoiceFormat[0]) {
+                            // Two modes here: If doFormat is false, we set up
+                            // currencyChoice.  If doFormat is true, we use the
+                            // previously created currencyChoice to format the
+                            // value in digitList.
+                            if (!doFormat) {
+                                // If the currency is handled by a ChoiceFormat,
+                                // then we're not going to use the expanded
+                                // patterns.  Instantiate the ChoiceFormat and
+                                // return.
+                                if (currencyChoice == null) {
+                                    currencyChoice = new ChoiceFormat(s);
+                                }
+                                // We could almost return null or "" here, since the
+                                // expanded affixes are almost not used at all
+                                // in this situation.  However, one method --
+                                // toPattern() -- still does use the expanded
+                                // affixes, in order to set up a padding
+                                // pattern.  We use the CURRENCY_SIGN as a
+                                // placeholder.
+                                s = String.valueOf(CURRENCY_SIGN);
+                            } else {
+                                FieldPosition pos = new FieldPosition(0); // ignored
+                                currencyChoice.format(digitList.getDouble(), buffer, pos);
+                                continue;
+                            }
+                        }
+                    } else {
+                        s = currency.getCurrencyCode();
+                    }
+                } else {
+                    s = intl ? symbols.getInternationalCurrencySymbol()
+                        : symbols.getCurrencySymbol();
+                }
+                buffer.append(s);
+                continue;
+            case PATTERN_PERCENT:
+                c = symbols.getPercent();
+                break;
+            case PATTERN_PER_MILLE:
+                c = symbols.getPerMill();
+                break;
+            case PATTERN_MINUS:
+                c = symbols.getMinusSign();
+                break;
+            }
+            buffer.append(c);
+        }
+    }
+
+    /**
+     * Append an affix to the given StringBuffer.
+     * @param buf buffer to append to
+     * @param isNegative
+     * @param isPrefix
+     */
+    private int appendAffix(StringBuffer buf, boolean isNegative,
+            boolean isPrefix, boolean parseAttr) {
+        if (currencyChoice != null) {
+            String affixPat = null;
+            if (isPrefix) {
+                affixPat = isNegative ? negPrefixPattern : posPrefixPattern;
+            } else {
+                affixPat = isNegative ? negSuffixPattern : posSuffixPattern;
+            }
+            StringBuffer affixBuf = new StringBuffer();
+            expandAffix(affixPat, null, affixBuf, true);
+            buf.append(affixBuf.toString());
+            return affixBuf.length();
+        }
+
+        String affix = null;
+        if (isPrefix) {
+            affix = isNegative ? negativePrefix : positivePrefix;
+        } else {
+            affix = isNegative ? negativeSuffix : positiveSuffix;
+        }
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+        // [Spark/CDL] Invoke formatAffix2Attribute to add attributes for affix
+        if (parseAttr) {
+            int offset = affix.indexOf(symbols.getCurrencySymbol());
+            if (-1 == offset) {
+                offset = affix.indexOf(symbols.getPercent());
+                if(-1 == offset) {
+                    offset = 0;
+                }
+            }
+            formatAffix2Attribute(affix, buf.length() + offset, buf.length()
+                    + affix.length());
+        }
+//#endif
+        buf.append(affix);
+        return affix.length();
+    }
+
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+    /*
+     * [Spark/CDL] This is a newly added method, used to add attributes for
+     * prefix and suffix.
+     */
+    private void formatAffix2Attribute(String affix, int begin, int end) {
+        // [Spark/CDL] It is the invoker's responsibility to ensure that, before
+        // the invocation of
+        // this method, attributes is not null.
+        // if( attributes == null ) return;
+        if (affix.indexOf(symbols.getCurrencySymbol()) > -1) {
+            addAttribute(Field.CURRENCY, begin, end);
+        } else if (affix.indexOf(symbols.getMinusSign()) > -1) {
+            addAttribute(Field.SIGN, begin, end);
+        } else if (affix.indexOf(symbols.getPercent()) > -1) {
+            addAttribute(Field.PERCENT, begin, end);
+        } else if (affix.indexOf(symbols.getPerMill()) > -1) {
+            addAttribute(Field.PERMILLE, begin, end);
+        }
+    }
+//#endif
+
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+    /*
+     * [Spark/CDL] Use this method to add attribute.
+     */
+    private void addAttribute(Field field, int begin, int end) {
+        FieldPosition pos = new FieldPosition(field);
+        pos.setBeginIndex(begin);
+        pos.setEndIndex(end);
+        attributes.add(pos);
+    }
+//#endif
+
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+    /**
+     * Format the object to an attributed string, and return the corresponding iterator
+     * Overrides superclass method.
+     * @stable ICU 3.6
+     */
+    // [Spark/CDL] 
+    public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
+        if (!(obj instanceof Number))
+            throw new IllegalArgumentException();
+        Number number = (Number) obj;
+        StringBuffer text = null;
+        attributes.clear();
+        if (obj instanceof BigInteger) {
+            text = format((BigInteger) number, new StringBuffer(),
+                    new FieldPosition(0), true);
+        } else if (obj instanceof java.math.BigDecimal) {
+            text = format((java.math.BigDecimal) number, new StringBuffer(),
+                    new FieldPosition(0), true);
+        } else if (obj instanceof Double) {
+            text = format(number.doubleValue(), new StringBuffer(),
+                    new FieldPosition(0), true);
+        } else if (obj instanceof Integer || obj instanceof Long) {
+            text = format(number.longValue(), new StringBuffer(),
+                    new FieldPosition(0), true);
+        }
+
+        AttributedString as = new AttributedString(text.toString());
+
+        // add NumberFormat field attributes to the AttributedString
+        for (int i = 0; i < attributes.size(); i++) {
+            FieldPosition pos = (FieldPosition) attributes.get(i);
+            Format.Field attribute = pos.getFieldAttribute();
+            as.addAttribute(attribute, attribute, pos.getBeginIndex(), pos
+                    .getEndIndex());
+        }
+
+        // return the CharacterIterator from AttributedString
+        return as.getIterator();
+    }
+//#endif
+    /**
+     * Append an affix pattern to the given StringBuffer.  Localize unquoted
+     * specials.
+     */
+    private void appendAffixPattern(StringBuffer buffer,
+                                    boolean isNegative, boolean isPrefix,
+                                    boolean localized) {
+        String affixPat = null;
+        if (isPrefix) {
+            affixPat = isNegative ? negPrefixPattern : posPrefixPattern;
+        } else {
+            affixPat = isNegative ? negSuffixPattern : posSuffixPattern;
+        }
+
+        // When there is a null affix pattern, we use the affix itself.
+        if (affixPat == null) {
+            String affix = null;
+            if (isPrefix) {
+                affix = isNegative ? negativePrefix : positivePrefix;
+            } else {
+                affix = isNegative ? negativeSuffix : positiveSuffix;
+            }
+            // Do this crudely for now:  Wrap everything in quotes.
+            buffer.append(QUOTE);
+            for (int i=0; i<affix.length(); ++i) {
+                char ch = affix.charAt(i);
+                if (ch == QUOTE) {
+                    buffer.append(ch);
+                }
+                buffer.append(ch);
+            }
+            buffer.append(QUOTE);
+            return;
+        }
+
+        if (!localized) {
+            buffer.append(affixPat);
+        } else {
+            int i, j;
+            for (i=0; i<affixPat.length(); ++i) {
+                char ch = affixPat.charAt(i);
+                switch (ch) {
+                case QUOTE:
+                    j = affixPat.indexOf(QUOTE, i+1);
+                    if (j < 0) {
+                        throw new IllegalArgumentException("Malformed affix pattern: " + affixPat);
+                    }
+                    buffer.append(affixPat.substring(i, j+1));
+                    i = j;
+                    continue;
+                case PATTERN_PER_MILLE:
+                    ch = symbols.getPerMill();
+                    break;
+                case PATTERN_PERCENT:
+                    ch = symbols.getPercent();
+                    break;
+                case PATTERN_MINUS:
+                    ch = symbols.getMinusSign();
+                    break;
+                }
+                //check if char is same as any other symbol
+                if(ch==symbols.getDecimalSeparator() ||
+                   ch==symbols.getGroupingSeparator() ){
+                    buffer.append(QUOTE);
+                    buffer.append(ch);
+                    buffer.append(QUOTE);
+                }else{
+                    buffer.append(ch);
+                }
+            }
+        }
+    }
+
+    /**
+     * <strong><font face=helvetica color=red>CHANGED</font></strong>
+     * Does the real work of generating a pattern.
+     */
+    private String toPattern(boolean localized) {
+        StringBuffer result = new StringBuffer();
+        char zero = localized ? symbols.getZeroDigit() : PATTERN_ZERO_DIGIT;
+        char digit = localized ? symbols.getDigit() : PATTERN_DIGIT;
+        char sigDigit = 0;
+        boolean useSigDig = areSignificantDigitsUsed();
+        if (useSigDig) {
+            sigDigit = localized ? symbols.getSignificantDigit() : PATTERN_SIGNIFICANT_DIGIT;
+        }
+        char group = localized ? symbols.getGroupingSeparator()
+                               : PATTERN_GROUPING_SEPARATOR;
+        int i;
+        int roundingDecimalPos = 0; // Pos of decimal in roundingDigits
+        String roundingDigits = null;
+        int padPos = (formatWidth > 0) ? padPosition : -1;
+        String padSpec = (formatWidth > 0)
+            ? new StringBuffer(2).
+                append(localized ? symbols.getPadEscape() : PATTERN_PAD_ESCAPE).
+                append(pad).toString()
+            : null;
+        if (roundingIncrementICU != null) {
+            i = roundingIncrementICU.scale();
+            roundingDigits = roundingIncrementICU.movePointRight(i).toString();
+            roundingDecimalPos = roundingDigits.length() - i;
+        }
+        for (int part=0; part<2; ++part) {
+            // variable not used int partStart = result.length();
+            if (padPos == PAD_BEFORE_PREFIX) {
+                result.append(padSpec);
+            }
+            /* Use original symbols read from resources in pattern
+             * eg. use "\u00A4" instead of "$" in Locale.US [Richard/GCL]
+             */
+            appendAffixPattern(result, part!=0, true, localized);
+            if (padPos == PAD_AFTER_PREFIX) {
+                result.append(padSpec);
+            }
+            int sub0Start = result.length();
+            int g = isGroupingUsed() ? Math.max(0, groupingSize) : 0;
+            if (g > 0 && groupingSize2 > 0 && groupingSize2 != groupingSize) {
+                g += groupingSize2;
+            }
+            int maxDig = 0, minDig = 0, maxSigDig = 0;
+            if (useSigDig) {
+                minDig = getMinimumSignificantDigits();
+                maxDig = maxSigDig = getMaximumSignificantDigits();
+            } else {
+                minDig = getMinimumIntegerDigits();
+                maxDig = getMaximumIntegerDigits();
+            }
+            if (useExponentialNotation) {
+                if (maxDig > MAX_SCIENTIFIC_INTEGER_DIGITS) {
+                    maxDig = 1;
+                }
+            } else if (useSigDig) {
+                maxDig = Math.max(maxDig, g+1);
+            } else {
+                maxDig = Math.max(Math.max(g, getMinimumIntegerDigits()),
+                                  roundingDecimalPos) + 1;
+            }
+            for (i = maxDig; i > 0; --i) {
+                if (!useExponentialNotation && i<maxDig &&
+                    isGroupingPosition(i)) {
+                    result.append(group);
+                }
+                if (useSigDig) {
+                    //  #@,@###   (maxSigDig == 5, minSigDig == 2)
+                    //  65 4321   (1-based pos, count from the right)
+                    // Use # if pos > maxSigDig or 1 <= pos <= (maxSigDig - minSigDig)
+                    // Use @ if (maxSigDig - minSigDig) < pos <= maxSigDig
+                    result.append((maxSigDig >= i && i > (maxSigDig - minDig)) ? sigDigit : digit);
+                } else {
+                    if (roundingDigits != null) {
+                        int pos = roundingDecimalPos - i;
+                        if (pos >= 0 && pos < roundingDigits.length()) {
+                            result.append((char) (roundingDigits.charAt(pos) - '0' + zero));
+                            continue;
+                        }
+                    }
+                    result.append(i<=minDig ? zero : digit);
+                }
+            }
+            if (!useSigDig) {
+                if (getMaximumFractionDigits() > 0 || decimalSeparatorAlwaysShown) {
+                    result.append(localized ? symbols.getDecimalSeparator() :
+                                  PATTERN_DECIMAL_SEPARATOR);
+                }
+                int pos = roundingDecimalPos;
+                for (i = 0; i < getMaximumFractionDigits(); ++i) {
+                    if (roundingDigits != null &&
+                        pos < roundingDigits.length()) {
+                        result.append(pos < 0 ? zero :
+                                      (char) (roundingDigits.charAt(pos) - '0' + zero));
+                        ++pos;
+                        continue;
+                    }
+                    result.append(i<getMinimumFractionDigits() ? zero : digit);
+                }
+            }
+            if (useExponentialNotation) {
+                if(localized ){
+                    result.append(symbols.getExponentSeparator() );
+                }else{
+                    result.append(PATTERN_EXPONENT);
+                }
+                if (exponentSignAlwaysShown) {
+                    result.append(localized ? symbols.getPlusSign() :
+                                  PATTERN_PLUS_SIGN);
+                }
+                for (i=0; i<minExponentDigits; ++i) {
+                    result.append(zero);
+                }
+            }
+            if (padSpec != null && !useExponentialNotation) {
+                int add = formatWidth - result.length() + sub0Start
+                    - ((part == 0)
+                       ? positivePrefix.length() + positiveSuffix.length()
+                       : negativePrefix.length() + negativeSuffix.length());
+                while (add > 0) {
+                    result.insert(sub0Start, digit);
+                    ++maxDig;
+                    --add;
+                    // Only add a grouping separator if we have at least
+                    // 2 additional characters to be added, so we don't
+                    // end up with ",###".
+                    if (add>1 && isGroupingPosition(maxDig)) {
+                        result.insert(sub0Start, group);
+                        --add;                        
+                    }
+                }
+            }
+            if (padPos == PAD_BEFORE_SUFFIX) {
+                result.append(padSpec);
+            }
+            /* Use original symbols read from resources in pattern
+             * eg. use "\u00A4" instead of "$" in Locale.US [Richard/GCL]
+             */
+            appendAffixPattern(result, part!=0, false, localized);
+            if (padPos == PAD_AFTER_SUFFIX) {
+                result.append(padSpec);
+            }
+            if (part == 0) {
+                if (negativeSuffix.equals(positiveSuffix) &&
+                    negativePrefix.equals( PATTERN_MINUS + positivePrefix)) {
+                    break;
+                } else {
+                    result.append(localized ? symbols.getPatternSeparator() :
+                                  PATTERN_SEPARATOR);
+                }
+            }
+        }
+        return result.toString();
+    }
+
+    /**
+     * Apply the given pattern to this Format object.  A pattern is a
+     * short-hand specification for the various formatting properties.
+     * These properties can also be changed individually through the
+     * various setter methods.
+     * <p>
+     * There is no limit to integer digits are set
+     * by this routine, since that is the typical end-user desire;
+     * use setMaximumInteger if you want to set a real value.
+     * For negative numbers, use a second pattern, separated by a semicolon
+     * <P>Example "#,#00.0#" -> 1,234.56
+     * <P>This means a minimum of 2 integer digits, 1 fraction digit, and
+     * a maximum of 2 fraction digits.
+     * <p>Example: "#,#00.0#;(#,#00.0#)" for negatives in parentheses.
+     * <p>In negative patterns, the minimum and maximum counts are ignored;
+     * these are presumed to be set in the positive pattern.
+     * @stable ICU 2.0
+     */
+    public void applyPattern( String pattern ) {
+        applyPattern( pattern, false );
+    }
+
+    /**
+     * Apply the given pattern to this Format object.  The pattern
+     * is assumed to be in a localized notation. A pattern is a
+     * short-hand specification for the various formatting properties.
+     * These properties can also be changed individually through the
+     * various setter methods.
+     * <p>
+     * There is no limit to integer digits are set
+     * by this routine, since that is the typical end-user desire;
+     * use setMaximumInteger if you want to set a real value.
+     * For negative numbers, use a second pattern, separated by a semicolon
+     * <P>Example "#,#00.0#" -> 1,234.56
+     * <P>This means a minimum of 2 integer digits, 1 fraction digit, and
+     * a maximum of 2 fraction digits.
+     * <p>Example: "#,#00.0#;(#,#00.0#)" for negatives in parantheses.
+     * <p>In negative patterns, the minimum and maximum counts are ignored;
+     * these are presumed to be set in the positive pattern.
+     * @stable ICU 2.0
+     */
+    public void applyLocalizedPattern( String pattern ) {
+        applyPattern( pattern, true );
+    }
+
+   
+    /**
+     * <strong><font face=helvetica color=red>CHANGED</font></strong>
+     * Does the real work of applying a pattern.
+     */
+    private void applyPattern(String pattern, boolean localized) {
+        applyPatternWithoutExpandAffix(pattern, localized);
+        expandAffixAdjustWidth(null);
+    }
+
+    private void expandAffixAdjustWidth(String pluralCount) {
+        /*Bug 4212072
+          Update the affix strings according to symbols in order to keep
+          the affix strings up to date.
+          [Richard/GCL]
+        */
+        expandAffixes(pluralCount);
+
+        // Now that we have the actual prefix and suffix, fix up formatWidth
+        if (formatWidth > 0) {
+            formatWidth += positivePrefix.length() + positiveSuffix.length();
+        }
+    }
+
+    private void applyPatternWithoutExpandAffix(String pattern, boolean localized) {
+        char zeroDigit         = PATTERN_ZERO_DIGIT; // '0'
+        char sigDigit          = PATTERN_SIGNIFICANT_DIGIT; // '@'
+        char groupingSeparator = PATTERN_GROUPING_SEPARATOR;
+        char decimalSeparator  = PATTERN_DECIMAL_SEPARATOR;
+        char percent           = PATTERN_PERCENT;
+        char perMill           = PATTERN_PER_MILLE;
+        char digit             = PATTERN_DIGIT; // '#'
+        char separator         = PATTERN_SEPARATOR;
+        String exponent        = String.valueOf(PATTERN_EXPONENT);
+        char plus              = PATTERN_PLUS_SIGN;
+        char padEscape         = PATTERN_PAD_ESCAPE;
+        char minus             = PATTERN_MINUS; //Bug 4212072 [Richard/GCL]
+        if (localized) {
+            zeroDigit         = symbols.getZeroDigit();
+            sigDigit          = symbols.getSignificantDigit();
+            groupingSeparator = symbols.getGroupingSeparator();
+            decimalSeparator  = symbols.getDecimalSeparator();
+            percent           = symbols.getPercent();
+            perMill           = symbols.getPerMill();
+            digit             = symbols.getDigit();
+            separator         = symbols.getPatternSeparator();
+            exponent          = symbols.getExponentSeparator();
+            plus              = symbols.getPlusSign();
+            padEscape         = symbols.getPadEscape();
+            minus             = symbols.getMinusSign(); //Bug 4212072 [Richard/GCL]
+        }
+        char nineDigit = (char) (zeroDigit + 9);
+
+        boolean gotNegative = false;
+
+        int pos = 0;
+        // Part 0 is the positive pattern.  Part 1, if present, is the negative
+        // pattern.
+        for (int part=0; part<2 && pos<pattern.length(); ++part) {
+            // The subpart ranges from 0 to 4: 0=pattern proper, 1=prefix,
+            // 2=suffix, 3=prefix in quote, 4=suffix in quote.  Subpart 0 is
+            // between the prefix and suffix, and consists of pattern
+            // characters.  In the prefix and suffix, percent, permille, and
+            // currency symbols are recognized and translated.
+            int subpart = 1, sub0Start = 0, sub0Limit = 0, sub2Limit = 0;
+
+            // It's important that we don't change any fields of this object
+            // prematurely.  We set the following variables for the multiplier,
+            // grouping, etc., and then only change the actual object fields if
+            // everything parses correctly.  This also lets us register
+            // the data from part 0 and ignore the part 1, except for the
+            // prefix and suffix.
+            StringBuffer prefix = new StringBuffer();
+            StringBuffer suffix = new StringBuffer();
+            int decimalPos = -1;
+            int multpl = 1;
+            int digitLeftCount = 0, zeroDigitCount = 0, digitRightCount = 0, sigDigitCount = 0;
+            byte groupingCount = -1;
+            byte groupingCount2 = -1;
+            int padPos = -1;
+            char padChar = 0;
+            int incrementPos = -1;
+            long incrementVal = 0;
+            byte expDigits = -1;
+            boolean expSignAlways = false;
+
+            // The affix is either the prefix or the suffix.
+            StringBuffer affix = prefix;
+
+            int start = pos;
+
+        PARTLOOP:
+            for (; pos < pattern.length(); ++pos) {
+                char ch = pattern.charAt(pos);
+                switch (subpart) {
+                case 0: // Pattern proper subpart (between prefix & suffix)
+                    // Process the digits, decimal, and grouping characters.  We
+                    // record five pieces of information.  We expect the digits
+                    // to occur in the pattern ####00.00####, and we record the
+                    // number of left digits, zero (central) digits, and right
+                    // digits.  The position of the last grouping character is
+                    // recorded (should be somewhere within the first two blocks
+                    // of characters), as is the position of the decimal point,
+                    // if any (should be in the zero digits).  If there is no
+                    // decimal point, then there should be no right digits.
+                    if (ch == digit) {
+                        if (zeroDigitCount > 0 || sigDigitCount > 0) {
+                            ++digitRightCount;
+                        } else {
+                            ++digitLeftCount;
+                        }
+                        if (groupingCount >= 0 && decimalPos < 0) {
+                            ++groupingCount;
+                        }
+                    } else if ((ch >= zeroDigit && ch <= nineDigit) ||
+                               ch == sigDigit) {
+                        if (digitRightCount > 0) {
+                            patternError("Unexpected '" + ch + '\'', pattern);
+                        }
+                        if (ch == sigDigit) {
+                            ++sigDigitCount;
+                        } else {
+                            ++zeroDigitCount;
+                            if (ch != zeroDigit) {
+                                int p = digitLeftCount + zeroDigitCount
+                                    + digitRightCount;
+                                if (incrementPos >= 0) {
+                                    while (incrementPos < p) {
+                                        incrementVal *= 10;
+                                        ++incrementPos;
+                                    }
+                                } else {
+                                    incrementPos = p;
+                                }
+                                incrementVal += ch - zeroDigit;
+                            }
+                        }
+                        if (groupingCount >= 0 && decimalPos < 0) {
+                            ++groupingCount;
+                        }
+                    } else if (ch == groupingSeparator) {
+                        /*Bug 4212072
+                          process the Localized pattern like "'Fr. '#'##0.05;'Fr.-'#'##0.05"
+                          (Locale="CH", groupingSeparator == QUOTE)                          
+                          [Richard/GCL]
+                        */
+                        if (ch == QUOTE && (pos+1) < pattern.length()) {
+                            char after = pattern.charAt(pos+1);
+                            if (!(after == digit || (after >= zeroDigit && after <= nineDigit))) {
+                                // A quote outside quotes indicates either the opening
+                                // quote or two quotes, which is a quote literal.  That is,
+                                // we have the first quote in 'do' or o''clock.
+                                if (after == QUOTE) {
+                                    ++pos;
+                                    // Fall through to append(ch)
+                                } else {
+                                    if (groupingCount < 0) {
+                                        subpart = 3; // quoted prefix subpart
+                                    } else {
+                                      // Transition to suffix subpart
+                                      subpart = 2; // suffix subpart
+                                      affix = suffix;
+                                      sub0Limit = pos--;
+                                    }
+                                    continue;
+                                }
+                            }
+                        }
+                        
+                        if (decimalPos >= 0) {
+                            patternError("Grouping separator after decimal", pattern);
+                        }
+                        groupingCount2 = groupingCount;
+                        groupingCount = 0;
+                    } else if (ch == decimalSeparator) {
+                        if (decimalPos >= 0) {
+                            patternError("Multiple decimal separators", pattern);
+                        }
+                        // Intentionally incorporate the digitRightCount,
+                        // even though it is illegal for this to be > 0
+                        // at this point.  We check pattern syntax below.
+                        decimalPos = digitLeftCount + zeroDigitCount + digitRightCount;
+                    } else {
+                        if (pattern.regionMatches(pos, exponent, 0, exponent.length())) {
+                            if (expDigits >= 0) {
+                                patternError("Multiple exponential symbols", pattern);
+                            }
+                            if (groupingCount >= 0) {
+                                patternError("Grouping separator in exponential", pattern);
+                            }
+                            pos += exponent.length();
+                            // Check for positive prefix
+                            if (pos < pattern.length()
+                                && pattern.charAt(pos) == plus) {
+                                expSignAlways = true;
+                                ++pos;
+                            }
+                            // Use lookahead to parse out the exponential part of the
+                            // pattern, then jump into suffix subpart.
+                            expDigits = 0;
+                            while (pos < pattern.length() &&
+                                   pattern.charAt(pos) == zeroDigit) {
+                                ++expDigits;
+                                ++pos;
+                            }
+                            
+                            // 1. Require at least one mantissa pattern digit
+                            // 2. Disallow "#+ @" in mantissa
+                            // 3. Require at least one exponent pattern digit
+                            if (((digitLeftCount + zeroDigitCount) < 1 &&
+                                 (sigDigitCount + digitRightCount) < 1) ||
+                                (sigDigitCount > 0 && digitLeftCount > 0) ||
+                                expDigits < 1) {
+                                patternError("Malformed exponential", pattern);
+                            }
+                        }
+                        // Transition to suffix subpart
+                        subpart = 2; // suffix subpart
+                        affix = suffix;
+                        sub0Limit = pos--; // backup: for() will increment
+                        continue;
+                    }
+                    break;
+                case 1: // Prefix subpart
+                case 2: // Suffix subpart
+                    // Process the prefix / suffix characters
+                    // Process unquoted characters seen in prefix or suffix
+                    // subpart.
+                    
+                    // Several syntax characters implicitly begins the
+                    // next subpart if we are in the prefix; otherwise
+                    // they are illegal if unquoted.
+                    if (ch == digit ||
+                        ch == groupingSeparator ||
+                        ch == decimalSeparator ||
+                        (ch >= zeroDigit && ch <= nineDigit) ||
+                        ch == sigDigit) {
+                        // Any of these characters implicitly begins the
+                        // next subpart if we are in the prefix
+                        if (subpart == 1) { // prefix subpart
+                            subpart = 0; // pattern proper subpart
+                            sub0Start = pos--; // Reprocess this character
+                            continue;
+                        } else if (ch == QUOTE) {
+                            /*Bug 4212072
+                              process the Localized pattern like "'Fr. '#'##0.05;'Fr.-'#'##0.05"
+                              (Locale="CH", groupingSeparator == QUOTE)                          
+                              [Richard/GCL]
+                            */
+                            // A quote outside quotes indicates either the opening
+                            // quote or two quotes, which is a quote literal.  That is,
+                            // we have the first quote in 'do' or o''clock.
+                            if ((pos+1) < pattern.length() &&
+                                pattern.charAt(pos+1) == QUOTE) {
+                                ++pos;
+                                affix.append(ch);
+                            } else {
+                                subpart += 2; // open quote
+                            }
+                            continue;
+                        }
+                        patternError("Unquoted special character '" + ch + '\'', pattern);
+                    } else if (ch == CURRENCY_SIGN) {
+                        // Use lookahead to determine if the currency sign is
+                        // doubled or not.
+                        boolean doubled = (pos + 1) < pattern.length() &&
+                            pattern.charAt(pos + 1) == CURRENCY_SIGN;
+                        /*Bug 4212072
+                         To meet the need of expandAffix(String, StirngBuffer)
+                         [Richard/GCL]
+                        */
+                        if (doubled) {
+                            ++pos; // Skip over the doubled character
+                            affix.append(ch); // append two: one here, one below
+                            if ((pos + 1) < pattern.length() &&
+                                pattern.charAt(pos + 1) == CURRENCY_SIGN) {
+                                ++pos; // Skip over the tripled character
+                                affix.append(ch); // append again
+                                currencySignCount = CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT;
+                            } else {
+                                currencySignCount = CURRENCY_SIGN_COUNT_IN_ISO_FORMAT;
+                            } 
+                        } else {
+                            currencySignCount = CURRENCY_SIGN_COUNT_IN_SYMBOL_FORMAT;
+                        }
+                        // Fall through to append(ch)
+                    } else if (ch == QUOTE) {
+                        // A quote outside quotes indicates either the opening
+                        // quote or two quotes, which is a quote literal.  That is,
+                        // we have the first quote in 'do' or o''clock.
+                        if((pos+1) < pattern.length()&&
+                            pattern.charAt(pos+1)==QUOTE){
+                            ++pos;
+                            affix.append(ch); // append two: one here, one below
+                        }else{
+                            subpart += 2; // open quote
+                        }
+                        // Fall through to append(ch)
+                    } else if (ch == separator) {
+                        // Don't allow separators in the prefix, and don't allow
+                        // separators in the second pattern (part == 1).
+                        if (subpart == 1 || part == 1) {
+                            patternError("Unquoted special character '" + ch + '\'', pattern);
+                        }
+                        sub2Limit = pos++;
+                        break PARTLOOP; // Go to next part
+                    } else if (ch == percent || ch == perMill) {
+                        // Next handle characters which are appended directly.
+                        if (multpl != 1) {
+                            patternError("Too many percent/permille characters", pattern);
+                        }
+                        multpl = (ch == percent) ? 100 : 1000;
+                        // Convert to non-localized pattern
+                        ch = (ch == percent) ? PATTERN_PERCENT : PATTERN_PER_MILLE;
+                        // Fall through to append(ch)
+                    } else if (ch == minus) {
+                        // Convert to non-localized pattern
+                        ch = PATTERN_MINUS;
+                        // Fall through to append(ch)
+                    } else if (ch == padEscape) {
+                        if (padPos >= 0) {
+                            patternError("Multiple pad specifiers", pattern);
+                        }
+                        if ((pos+1) == pattern.length()) {
+                            patternError("Invalid pad specifier", pattern);
+                        }
+                        padPos = pos++; // Advance past pad char
+                        padChar = pattern.charAt(pos);
+                        continue;
+                    }
+                    affix.append(ch);
+                    break;
+                case 3: // Prefix subpart, in quote
+                case 4: // Suffix subpart, in quote
+                    // A quote within quotes indicates either the closing
+                    // quote or two quotes, which is a quote literal.  That is,
+                    // we have the second quote in 'do' or 'don''t'.
+                    if (ch == QUOTE) {
+                        if ((pos+1) < pattern.length() &&
+                            pattern.charAt(pos+1) == QUOTE) {
+                            ++pos; 
+                            affix.append(ch);
+                        } else {
+                            subpart -= 2; // close quote
+                        }
+                        // Fall through to append(ch)
+                    }
+                    // NOTE: In ICU 2.2 there was code here to parse quoted
+                    // percent and permille characters _within quotes_ and give
+                    // them special meaning.  This is incorrect, since quoted
+                    // characters are literals without special meaning.
+                    affix.append(ch);
+                    break;                    
+                }
+            }
+            
+            if (subpart == 3 || subpart == 4) {
+                patternError("Unterminated quote", pattern);
+            }
+
+            if (sub0Limit == 0) {
+                sub0Limit = pattern.length();
+            }
+
+            if (sub2Limit == 0) {
+                sub2Limit = pattern.length();
+            }
+
+            /* Handle patterns with no '0' pattern character.  These patterns
+             * are legal, but must be recodified to make sense.  "##.###" ->
+             * "#0.###".  ".###" -> ".0##".
+             *
+             * We allow patterns of the form "####" to produce a zeroDigitCount
+             * of zero (got that?); although this seems like it might make it
+             * possible for format() to produce empty strings, format() checks
+             * for this condition and outputs a zero digit in this situation.
+             * Having a zeroDigitCount of zero yields a minimum integer digits
+             * of zero, which allows proper round-trip patterns.  We don't want
+             * "#" to become "#0" when toPattern() is called (even though that's
+             * what it really is, semantically).
+             */
+            if (zeroDigitCount == 0 && sigDigitCount == 0 &&
+                digitLeftCount > 0 && decimalPos >= 0) {
+                // Handle "###.###" and "###." and ".###"
+                int n = decimalPos;
+                if (n == 0) ++n; // Handle ".###"
+                digitRightCount = digitLeftCount - n;
+                digitLeftCount = n - 1;
+                zeroDigitCount = 1;
+            }
+
+            // Do syntax checking on the digits, decimal points, and quotes.
+            if ((decimalPos < 0 && digitRightCount > 0 && sigDigitCount == 0) ||
+                (decimalPos >= 0 &&
+                 (sigDigitCount > 0 ||
+                  decimalPos < digitLeftCount ||
+                  decimalPos > (digitLeftCount + zeroDigitCount))) ||
+                groupingCount == 0 || groupingCount2 == 0 ||
+                (sigDigitCount > 0 && zeroDigitCount > 0) ||
+                subpart > 2) { // subpart > 2 == unmatched quote
+                patternError("Malformed pattern", pattern);
+            }
+
+            // Make sure pad is at legal position before or after affix.
+            if (padPos >= 0) {
+                if (padPos == start) {
+                    padPos = PAD_BEFORE_PREFIX;
+                } else if (padPos+2 == sub0Start) {
+                    padPos = PAD_AFTER_PREFIX;
+                } else if (padPos == sub0Limit) {
+                    padPos = PAD_BEFORE_SUFFIX;
+                } else if (padPos+2 == sub2Limit) {
+                    padPos = PAD_AFTER_SUFFIX;
+                } else {
+                    patternError("Illegal pad position", pattern);
+                }
+            }
+
+            if (part == 0) {
+                // Set negative affixes temporarily to match the positive
+                // affixes.  Fix this up later after processing both parts.
+                /*Bug 4212072
+                  To meet the need of expandAffix(String, StirngBuffer)
+                  [Richard/GCL]
+                */
+                posPrefixPattern = negPrefixPattern = prefix.toString();
+                posSuffixPattern = negSuffixPattern = suffix.toString();
+
+                useExponentialNotation = (expDigits >= 0);
+                if (useExponentialNotation) {
+                    minExponentDigits = expDigits;
+                    exponentSignAlwaysShown = expSignAlways;
+                }
+                int digitTotalCount = digitLeftCount + zeroDigitCount + digitRightCount;
+                // The effectiveDecimalPos is the position the decimal is at or
+                // would be at if there is no decimal.  Note that if
+                // decimalPos<0, then digitTotalCount == digitLeftCount +
+                // zeroDigitCount.
+                int effectiveDecimalPos = decimalPos >= 0 ? decimalPos : digitTotalCount;
+                boolean useSigDig = (sigDigitCount > 0);
+                setSignificantDigitsUsed(useSigDig);
+                if (useSigDig) {
+                    setMinimumSignificantDigits(sigDigitCount);
+                    setMaximumSignificantDigits(sigDigitCount + digitRightCount);
+                } else {
+                    int minInt = effectiveDecimalPos - digitLeftCount;
+                    setMinimumIntegerDigits(minInt);
+                    /*Upper limit on integer and fraction digits for a Java double
+                      [Richard/GCL]
+                    */
+                    setMaximumIntegerDigits(useExponentialNotation
+                        ? digitLeftCount + minInt : DOUBLE_INTEGER_DIGITS);
+                    setMaximumFractionDigits(decimalPos >= 0
+                        ? (digitTotalCount - decimalPos) : 0);
+                    setMinimumFractionDigits(decimalPos >= 0
+                        ? (digitLeftCount + zeroDigitCount - decimalPos) : 0);
+                }
+                setGroupingUsed(groupingCount > 0);
+                this.groupingSize = (groupingCount > 0) ? groupingCount : 0;
+                this.groupingSize2 = (groupingCount2 > 0 && groupingCount2 != groupingCount)
+                    ? groupingCount2 : 0;
+                this.multiplier = multpl;
+                setDecimalSeparatorAlwaysShown(decimalPos == 0
+                        || decimalPos == digitTotalCount);
+                if (padPos >= 0) {
+                    padPosition = padPos;
+                    formatWidth = sub0Limit - sub0Start; // to be fixed up below
+                    pad = padChar;
+                } else {
+                    formatWidth = 0;
+                }
+                if (incrementVal != 0) {
+                    // BigDecimal scale cannot be negative (even though
+                    // this makes perfect sense), so we need to handle this.
+                    int scale = incrementPos - effectiveDecimalPos;
+                    roundingIncrementICU =
+                        BigDecimal.valueOf(incrementVal, scale > 0 ? scale : 0);
+                    if (scale < 0) {
+                        roundingIncrementICU =
+                            roundingIncrementICU.movePointRight(-scale);
+                    }
+                    setRoundingDouble();
+                    roundingMode = BigDecimal.ROUND_HALF_EVEN;
+                } else {
+                    setRoundingIncrement((BigDecimal)null);
+                }
+            } else {
+                /*Bug 4212072
+                  To meet the need of expandAffix(String, StirngBuffer)
+                  [Richard/GCL]
+                */
+                negPrefixPattern = prefix.toString();
+                negSuffixPattern = suffix.toString();
+                gotNegative = true;
+            }
+        }
+
+        /*Bug 4140009
+          Process the empty pattern
+          [Richard/GCL]
+        */
+        if (pattern.length() == 0) {
+            posPrefixPattern = posSuffixPattern = "";
+            setMinimumIntegerDigits(0);
+            setMaximumIntegerDigits(DOUBLE_INTEGER_DIGITS);
+            setMinimumFractionDigits(0);
+            setMaximumFractionDigits(DOUBLE_FRACTION_DIGITS);
+        }
+        
+        // If there was no negative pattern, or if the negative pattern is
+        // identical to the positive pattern, then prepend the minus sign to the
+        // positive pattern to form the negative pattern.
+        /*Bug 4212072
+          To meet the need of expandAffix(String, StirngBuffer)
+          [Richard/GCL]
+        */
+        if (!gotNegative ||
+            (negPrefixPattern.equals(posPrefixPattern)
+             && negSuffixPattern.equals(posSuffixPattern))) {
+            negSuffixPattern = posSuffixPattern;
+            negPrefixPattern = PATTERN_MINUS + posPrefixPattern;
+        }
+        setLocale(null, null);
+        // save the pattern
+        formatPattern = pattern;
+        // initialize currencyPluralInfo if needed 
+        if (currencySignCount == CURRENCY_SIGN_COUNT_IN_PLURAL_FORMAT &&
+            currencyPluralInfo == null) { 
+            currencyPluralInfo = new CurrencyPluralInfo(symbols.getLocale());
+        }
+    }
+
+    /**
+     * Centralizes the setting of the roundingDouble and roundingDoubleReciprocal.
+     */
+    private void setRoundingDouble() {
+        if (roundingIncrementICU == null) {
+            roundingDouble = 0.0d;
+            roundingDoubleReciprocal = 0.0d;
+        } else {
+            roundingDouble = roundingIncrementICU.doubleValue();
+            setRoundingDoubleReciprocal(BigDecimal.ONE.divide(roundingIncrementICU,BigDecimal.ROUND_HALF_EVEN).doubleValue());
+        }
+    }
+
+    private void patternError(String msg, String pattern) {
+        throw new IllegalArgumentException(msg + " in pattern \"" + pattern + '"');
+    }
+
+    /*Rewrite the following 4 "set" methods
+      Upper limit on integer and fraction digits for a Java double 
+      [Richard/GCL]
+    */
+    /**
+     * Sets the maximum number of digits allowed in the integer portion of a
+     * number. This override limits the integer digit count to 309.
+     * @see NumberFormat#setMaximumIntegerDigits
+     * @stable ICU 2.0
+     */
+    public void setMaximumIntegerDigits(int newValue) {
+        super.setMaximumIntegerDigits(Math.min(newValue, DOUBLE_INTEGER_DIGITS));
+    }
+
+    /**
+     * Sets the minimum number of digits allowed in the integer portion of a
+     * number. This override limits the integer digit count to 309.
+     * @see NumberFormat#setMinimumIntegerDigits
+     * @stable ICU 2.0
+     */
+    public void setMinimumIntegerDigits(int newValue) {
+        super.setMinimumIntegerDigits(Math.min(newValue, DOUBLE_INTEGER_DIGITS));
+    }
+
+    /**
+     * Returns the minimum number of significant digits that will be
+     * displayed. This value has no effect unless areSignificantDigitsUsed()
+     * returns true.
+     * @return the fewest significant digits that will be shown
+     * @stable ICU 3.0
+     */
+    public int getMinimumSignificantDigits() {
+        return minSignificantDigits;
+    }
+
+    /**
+     * Returns the maximum number of significant digits that will be
+     * displayed. This value has no effect unless areSignificantDigitsUsed()
+     * returns true.
+     * @return the most significant digits that will be shown
+     * @stable ICU 3.0
+     */
+    public int getMaximumSignificantDigits() {
+        return maxSignificantDigits;
+    }
+
+    /**
+     * Sets the minimum number of significant digits that will be
+     * displayed.  If <code>min</code> is less than one then it is set
+     * to one.  If the maximum significant digits count is less than
+     * <code>min</code>, then it is set to <code>min</code>. This
+     * value has no effect unless areSignificantDigitsUsed() returns true.
+     * @param min the fewest significant digits to be shown 
+     * @stable ICU 3.0
+     */
+    public void setMinimumSignificantDigits(int min) {
+        if (min < 1) {
+            min = 1;   
+        }
+        // pin max sig dig to >= min
+        int max = Math.max(maxSignificantDigits, min);
+        minSignificantDigits = min;
+        maxSignificantDigits = max;
+    }
+
+    /**
+     * Sets the maximum number of significant digits that will be
+     * displayed.  If <code>max</code> is less than one then it is set
+     * to one.  If the minimum significant digits count is greater
+     * than <code>max</code>, then it is set to <code>max</code>. This
+     * value has no effect unless areSignificantDigitsUsed() returns true.
+     * @param max the most significant digits to be shown 
+     * @stable ICU 3.0
+     */
+    public void setMaximumSignificantDigits(int max) {
+        if (max < 1) {
+            max = 1;
+        }
+        // pin min sig dig to 1..max
+        int min = Math.min(minSignificantDigits, max);
+        minSignificantDigits = min;
+        maxSignificantDigits = max;
+    }
+
+    /**
+     * Returns true if significant digits are in use or false if
+     * integer and fraction digit counts are in use.
+     * @return true if significant digits are in use
+     * @stable ICU 3.0
+     */
+    public boolean areSignificantDigitsUsed() {
+        return useSignificantDigits;
+    }
+
+    /**
+     * Sets whether significant digits are in use, or integer and
+     * fraction digit counts are in use.
+     * @param useSignificantDigits true to use significant digits, or
+     * false to use integer and fraction digit counts
+     * @stable ICU 3.0
+     */
+    public void setSignificantDigitsUsed(boolean useSignificantDigits) {
+        this.useSignificantDigits = useSignificantDigits;
+    }
+
+    /**
+     * 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 through the application of a new pattern.
+     * @param theCurrency new currency object to use.  Must not be
+     * null.
+     * @stable ICU 2.2
+     */
+    public void setCurrency(Currency theCurrency) {
+        // If we are a currency format, then modify our affixes to
+        // encode the currency symbol for the given currency in our
+        // locale, and adjust the decimal digits and rounding for the
+        // given currency.
+
+        super.setCurrency(theCurrency);
+        if (theCurrency != null) {
+            boolean[] isChoiceFormat = new boolean[1];
+            String s = theCurrency.getName(symbols.getULocale(),
+                    Currency.SYMBOL_NAME,
+                    isChoiceFormat);
+                symbols.setCurrencySymbol(s);
+                symbols.setInternationalCurrencySymbol(theCurrency.getCurrencyCode());
+        }
+
+        if (currencySignCount > 0) {
+            if (theCurrency != null) {
+                setRoundingIncrement(theCurrency.getRoundingIncrement());
+                int d = theCurrency.getDefaultFractionDigits();
+                setMinimumFractionDigits(d);
+                setMaximumFractionDigits(d);
+            }
+            expandAffixes(null);
+        }
+    }
+
+    /**
+     * Returns the currency in effect for this formatter.  Subclasses
+     * should override this method as needed.  Unlike getCurrency(),
+     * this method should never return null.
+     * @internal
+     * @deprecated This API is ICU internal only.
+     */
+    protected Currency getEffectiveCurrency() {
+        Currency c = getCurrency();
+        if (c == null) {
+            c = Currency.getInstance(symbols.getInternationalCurrencySymbol());
+        }
+        return c;
+    }
+
+    /**
+     * Sets the maximum number of digits allowed in the fraction portion of a
+     * number. This override limits the fraction digit count to 340.
+     * @see NumberFormat#setMaximumFractionDigits
+     * @stable ICU 2.0
+     */
+    public void setMaximumFractionDigits(int newValue) {
+        super.setMaximumFractionDigits(Math.min(newValue, DOUBLE_FRACTION_DIGITS));
+    }
+
+    /**
+     * Sets the minimum number of digits allowed in the fraction portion of a
+     * number. This override limits the fraction digit count to 340.
+     * @see NumberFormat#setMinimumFractionDigits
+     * @stable ICU 2.0
+     */
+    public void setMinimumFractionDigits(int newValue) {
+        super.setMinimumFractionDigits(Math.min(newValue, DOUBLE_FRACTION_DIGITS));
+    }
+
+    /**
+     * Sets whether {@link #parse(String, ParsePosition)} method returns BigDecimal.
+     * The default value is false.
+     * @param value true if {@link #parse(String, ParsePosition)} method returns
+     * BigDecimal.
+     * @stable ICU 3.6
+     */
+    public void setParseBigDecimal(boolean value) {
+        parseBigDecimal = value;
+    }
+
+    /**
+     * Returns whether {@link #parse(String, ParsePosition)} method returns BigDecimal.
+     * @return true if {@link #parse(String, ParsePosition)} method returns BigDecimal.
+     * @stable ICU 3.6
+     */
+    public boolean isParseBigDecimal() {
+        return parseBigDecimal;
+    }
+
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+    private void writeObject(ObjectOutputStream stream) throws IOException {
+// Doug, do we need this anymore?
+//            if (roundingIncrementICU != null) {
+//                roundingIncrement = roundingIncrementICU.toBigDecimal();
+//            }
+
+        // Ticket#6449
+        // Format.Field instances are not serializable.  When formatToCharacterIterator
+        // is called, attributes (ArrayList) stores FieldPosition instances with
+        // NumberFormat.Field.  Because NumberFormat.Field is not serializable, we need
+        // to clear the contents of the list when writeObject is called.  We could remove
+        // the field or make it transient, but it will break serialization compatibility.
+        attributes.clear();
+
+        stream.defaultWriteObject();
+    }
+//#endif
+
+    /**
+     * First, read the default serializable fields from the stream.  Then
+     * if <code>serialVersionOnStream</code> is less than 1, indicating that
+     * the stream was written by JDK 1.1, initialize <code>useExponentialNotation</code>
+     * to false, since it was 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();
+        /*Bug 4185761 validate fields
+          [Richard/GCL]
+        */
+        // We only need to check the maximum counts because NumberFormat
+        // .readObject has already ensured that the maximum is greater than the
+        // minimum count.
+        /*Commented for compatibility with previous version, and reserved for further use
+        if (getMaximumIntegerDigits() > DOUBLE_INTEGER_DIGITS ||
+            getMaximumFractionDigits() > DOUBLE_FRACTION_DIGITS) {
+            throw new InvalidObjectException("Digit count out of range");
+        }*/
+        /* Truncate the maximumIntegerDigits to DOUBLE_INTEGER_DIGITS and maximumFractionDigits
+         * to DOUBLE_FRACTION_DIGITS
+         */
+        if (getMaximumIntegerDigits() > DOUBLE_INTEGER_DIGITS) {
+             setMaximumIntegerDigits(DOUBLE_INTEGER_DIGITS);
+        }
+        if (getMaximumFractionDigits() > DOUBLE_FRACTION_DIGITS) {
+            setMaximumFractionDigits(DOUBLE_FRACTION_DIGITS);
+        }
+        if (serialVersionOnStream < 2) {
+            exponentSignAlwaysShown = false;
+            setInternalRoundingIncrement(null);
+            setRoundingDouble();
+            roundingMode = BigDecimal.ROUND_HALF_EVEN;
+            formatWidth = 0;
+            pad = ' ';
+            padPosition = PAD_BEFORE_PREFIX;
+            if (serialVersionOnStream < 1) {
+                // Didn't have exponential fields
+                useExponentialNotation = false;
+            }
+        }
+        if (serialVersionOnStream < 3) {
+            // Versions prior to 3 do not store a currency object.
+            // Create one to match the DecimalFormatSymbols object.
+            setCurrencyForSymbols();
+        }
+        serialVersionOnStream = currentSerialVersion;
+        digitList = new DigitList();
+
+//#if defined(FOUNDATION10)
+//#else
+        if (roundingIncrement != null) {
+            setInternalRoundingIncrement(new BigDecimal(roundingIncrement));
+            setRoundingDouble();
+        }   
+//#endif
+    }
+
+
+    private void setInternalRoundingIncrement(BigDecimal value) {
+        roundingIncrementICU = value;
+//#if defined(FOUNDATION10)
+//#else
+        roundingIncrement = value == null ? null : value.toBigDecimal();
+//#endif
+    }
+
+    //----------------------------------------------------------------------
+    // INSTANCE VARIABLES
+    //----------------------------------------------------------------------
+
+    private transient DigitList digitList = new DigitList();
+
+    /**
+     * The symbol used as a prefix when formatting positive numbers, e.g. "+".
+     *
+     * @serial
+     * @see #getPositivePrefix
+     */
+    private String  positivePrefix = "";
+
+    /**
+     * The symbol used as a suffix when formatting positive numbers.
+     * This is often an empty string.
+     *
+     * @serial
+     * @see #getPositiveSuffix
+     */
+    private String  positiveSuffix = "";
+
+    /**
+     * The symbol used as a prefix when formatting negative numbers, e.g. "-".
+     *
+     * @serial
+     * @see #getNegativePrefix
+     */
+    private String  negativePrefix = "-";
+
+    /**
+     * The symbol used as a suffix when formatting negative numbers.
+     * This is often an empty string.
+     *
+     * @serial
+     * @see #getNegativeSuffix
+     */
+    private String  negativeSuffix = "";
+    
+    /**
+     * The prefix pattern for non-negative numbers.  This variable corresponds
+     * to <code>positivePrefix</code>.
+     *
+     * <p>This pattern is expanded by the method <code>expandAffix()</code> to
+     * <code>positivePrefix</code> to update the latter to reflect changes in
+     * <code>symbols</code>.  If this variable is <code>null</code> then
+     * <code>positivePrefix</code> is taken as a literal value that does not
+     * change when <code>symbols</code> changes.  This variable is always
+     * <code>null</code> for <code>DecimalFormat</code> objects older than
+     * stream version 2 restored from stream.
+     *
+     * @serial
+     */
+    //[Richard/GCL]
+    private String posPrefixPattern;
+
+    /**
+     * The suffix pattern for non-negative numbers.  This variable corresponds
+     * to <code>positiveSuffix</code>.  This variable is analogous to
+     * <code>posPrefixPattern</code>; see that variable for further
+     * documentation.
+     *
+     * @serial
+     */
+    //[Richard/GCL]
+    private String posSuffixPattern;
+
+    /**
+     * The prefix pattern for negative numbers.  This variable corresponds
+     * to <code>negativePrefix</code>.  This variable is analogous to
+     * <code>posPrefixPattern</code>; see that variable for further
+     * documentation.
+     *
+     * @serial
+     */
+    //[Richard/GCL]
+    private String negPrefixPattern;
+
+    /**
+     * The suffix pattern for negative numbers.  This variable corresponds
+     * to <code>negativeSuffix</code>.  This variable is analogous to
+     * <code>posPrefixPattern</code>; see that variable for further
+     * documentation.
+     *
+     * @serial
+     */
+    //[Richard/GCL]
+    private String negSuffixPattern;
+
+
+
+    /**
+     * Formatter for ChoiceFormat-based currency names.  If this field
+     * is not null, then delegate to it to format currency symbols.
+     * @since ICU 2.6
+     */
+    private ChoiceFormat currencyChoice;
+
+    /**
+     * The multiplier for use in percent, permill, etc.
+     *
+     * @serial
+     * @see #getMultiplier
+     */
+    private int     multiplier = 1;
+    
+    /**
+     * The number of digits between grouping separators in the integer
+     * portion of a number.  Must be greater than 0 if
+     * <code>NumberFormat.groupingUsed</code> is true.
+     *
+     * @serial
+     * @see #getGroupingSize
+     * @see NumberFormat#isGroupingUsed
+     */
+    private byte    groupingSize = 3;  // invariant, > 0 if useThousands
+
+    // [NEW]
+    /**
+     * The secondary grouping size.  This is only used for Hindi
+     * numerals, which use a primary grouping of 3 and a secondary
+     * grouping of 2, e.g., "12,34,567".  If this value is less than
+     * 1, then secondary grouping is equal to the primary grouping.
+     * 
+     */
+    private byte    groupingSize2 = 0;
+    
+    /**
+     * If true, forces the decimal separator to always appear in a formatted
+     * number, even if the fractional part of the number is zero.
+     *
+     * @serial
+     * @see #isDecimalSeparatorAlwaysShown
+     */
+    private boolean decimalSeparatorAlwaysShown = false;
+    
+    
+    /**
+     * The <code>DecimalFormatSymbols</code> object used by this format.
+     * It contains the symbols used to format numbers, e.g. the grouping separator,
+     * decimal separator, and so on.
+     *
+     * @serial
+     * @see #setDecimalFormatSymbols
+     * @see DecimalFormatSymbols
+     */
+    private DecimalFormatSymbols symbols = null; // LIU new DecimalFormatSymbols();
+
+    /**
+     * True to use significant digits rather than integer and fraction
+     * digit counts.
+     * @serial
+     * @since ICU 3.0
+     */
+    private boolean useSignificantDigits = false;
+
+    /**
+     * The minimum number of significant digits to show.  Must be >= 1
+     * and <= maxSignificantDigits.  Ignored unless
+     * useSignificantDigits == true.
+     * @serial
+     * @since ICU 3.0
+     */
+    private int minSignificantDigits = 1;
+
+    /**
+     * The maximum number of significant digits to show.  Must be >=
+     * minSignficantDigits.  Ignored unless useSignificantDigits ==
+     * true.
+     * @serial
+     * @since ICU 3.0
+     */
+    private int maxSignificantDigits = 6;
+
+    /**
+     * True to force the use of exponential (i.e. scientific) notation when formatting
+     * numbers.
+     * <p>
+     * Note that the JDK 1.2 public API provides no way to set this field,
+     * even though it is supported by the implementation and the stream format.
+     * The intent is that this will be added to the API in the future.
+     *
+     * @serial
+     */
+    private boolean useExponentialNotation;  // Newly persistent in JDK 1.2
+
+    /**
+     * The minimum number of digits used to display the exponent when a number is
+     * formatted in exponential notation.  This field is ignored if
+     * <code>useExponentialNotation</code> is not true.
+     * <p>
+     * Note that the JDK 1.2 public API provides no way to set this field,
+     * even though it is supported by the implementation and the stream format.
+     * The intent is that this will be added to the API in the future.
+     *
+     * @serial
+     */
+    private byte    minExponentDigits;       // Newly persistent in JDK 1.2
+
+    // [NEW]
+    /**
+     * If true, the exponent is always prefixed with either the plus
+     * sign or the minus sign.  Otherwise, only negative exponents are
+     * prefixed with the minus sign.  This has no effect unless
+     * <code>useExponentialNotation</code> is true.
+     * @serial
+     * @since AlphaWorks NumberFormat
+     */
+    private boolean exponentSignAlwaysShown = false;
+
+//#if defined(FOUNDATION10)
+//#else
+    // [NEW]
+    /**
+     * The value to which numbers are rounded during formatting.  For example,
+     * if the rounding increment is 0.05, then 13.371 would be formatted as
+     * 13.350, assuming 3 fraction digits.  Has the value <code>null</code> if
+     * rounding is not in effect, or a positive value if rounding is in effect.
+     * Default value <code>null</code>.
+     * @serial
+     * @since AlphaWorks NumberFormat
+     */
+    // Note: this is kept in sync with roundingIncrementICU.
+    // it is only kept around to avoid a conversion when formatting a java.math.BigDecimal
+    private java.math.BigDecimal roundingIncrement = null;
+//#endif
+
+    // [NEW]
+    /**
+     * The value to which numbers are rounded during formatting.  For example,
+     * if the rounding increment is 0.05, then 13.371 would be formatted as
+     * 13.350, assuming 3 fraction digits.  Has the value <code>null</code> if
+     * rounding is not in effect, or a positive value if rounding is in effect.
+     * Default value <code>null</code>.
+     * WARNING: the roundingIncrement value is the one serialized.
+     * @serial
+     * @since AlphaWorks NumberFormat
+     */
+    private transient BigDecimal roundingIncrementICU = null;
+
+    // [NEW]
+    /**
+     * The rounding increment as a double.  If this value is <= 0, then no
+     * rounding is done.  This value is
+     * <code>roundingIncrementICU.doubleValue()</code>.  Default value 0.0.
+     */
+    private transient double roundingDouble = 0.0;
+
+    // [NEW]
+    /**
+     * If the roundingDouble is the reciprocal of an integer (the most common case!),
+     * this is set to be that integer. Otherwise it is 0.0.
+     */
+    private transient double roundingDoubleReciprocal = 0.0;
+
+    // [NEW]
+    /**
+     * The rounding mode.  This value controls any rounding operations which
+     * occur when applying a rounding increment or when reducing the number of
+     * fraction digits to satisfy a maximum fraction digits limit.  The value
+     * may assume any of the <code>BigDecimal</code> rounding mode values.
+     * Default value <code>BigDecimal.ROUND_HALF_EVEN</code>.
+     * @serial
+     * @since AlphaWorks NumberFormat
+     */
+    private int roundingMode = BigDecimal.ROUND_HALF_EVEN;
+
+    // [NEW]
+    /**
+     * Operations on <code>BigDecimal</code> numbers are controlled by a
+     * {@link MathContext} object, which provides the context (precision and
+     * other information) for the operation. The default <code>MathContext</code> 
+     * settings are <code>digits=0, form=PLAIN, lostDigits=false, 
+     * roundingMode=ROUND_HALF_UP</code>; these settings perform fixed point 
+     * arithmetic with unlimited precision, as defined for the original BigDecimal 
+     * class in Java 1.1 and Java 1.2
+     */
+    private MathContext mathContext = new MathContext(0, MathContext.PLAIN); // context for plain unlimited math
+
+    // [NEW]
+    /**
+     * The padded format width, or zero if there is no padding.  Must
+     * be >= 0.  Default value zero.
+     * @serial
+     * @since AlphaWorks NumberFormat
+     */
+    private int formatWidth = 0;
+
+    // [NEW]
+    /**
+     * The character used to pad the result of format to
+     * <code>formatWidth</code>, if padding is in effect.  Default value ' '.
+     * @serial
+     * @since AlphaWorks NumberFormat
+     */
+    private char pad = ' ';
+
+    // [NEW]
+    /**
+     * The position in the string at which the <code>pad</code> character
+     * will be inserted, if padding is in effect.  Must have a value from
+     * <code>PAD_BEFORE_PREFIX</code> to <code>PAD_AFTER_SUFFIX</code>.
+     * Default value <code>PAD_BEFORE_PREFIX</code>.
+     * @serial
+     * @since AlphaWorks NumberFormat
+     */
+    private int padPosition = PAD_BEFORE_PREFIX;
+
+    /**
+     * True if {@link #parse(String, ParsePosition)} to return BigDecimal
+     * rather than Long, Double or BigDecimal except special values.
+     * This property is introduced for J2SE 5 compatibility support.
+     * @serial
+     * @since ICU 3.6
+     * @see #setParseBigDecimal(boolean)
+     * @see #isParseBigDecimal()
+     */
+    private boolean parseBigDecimal = false;
+
+    //----------------------------------------------------------------------
+
+    static final int currentSerialVersion = 3;
+
+    /**
+     * The internal serial version which says which version was written
+     * Possible values are:
+     * <ul>
+     * <li><b>0</b> (default): versions before JDK 1.2
+     * <li><b>1</b>: version from JDK 1.2 and later, which includes the two new fields
+     *      <code>useExponentialNotation</code> and <code>minExponentDigits</code>.
+     * <li><b>2</b>: version on AlphaWorks, which adds roundingMode, formatWidth,
+     *      pad, padPosition, exponentSignAlwaysShown, roundingIncrement.
+     * <li><b>3</b>: ICU 2.2.  Adds currency object.
+     * </ul>
+     * @serial */
+    private int serialVersionOnStream = currentSerialVersion;
+
+    //----------------------------------------------------------------------
+    // CONSTANTS
+    //----------------------------------------------------------------------
+
+    // [NEW]
+    /**
+     * Constant for <code>getPadPosition()</code> and
+     * <code>setPadPosition()</code> specifying pad characters inserted before
+     * the prefix.
+     * @see #setPadPosition
+     * @see #getPadPosition
+     * @see #PAD_AFTER_PREFIX
+     * @see #PAD_BEFORE_SUFFIX
+     * @see #PAD_AFTER_SUFFIX
+     * @stable ICU 2.0
+     */
+    public static final int PAD_BEFORE_PREFIX = 0;
+
+    // [NEW]
+    /**
+     * Constant for <code>getPadPosition()</code> and
+     * <code>setPadPosition()</code> specifying pad characters inserted after
+     * the prefix.
+     * @see #setPadPosition
+     * @see #getPadPosition
+     * @see #PAD_BEFORE_PREFIX
+     * @see #PAD_BEFORE_SUFFIX
+     * @see #PAD_AFTER_SUFFIX
+     * @stable ICU 2.0
+     */
+    public static final int PAD_AFTER_PREFIX  = 1;
+
+    // [NEW]
+    /**
+     * Constant for <code>getPadPosition()</code> and
+     * <code>setPadPosition()</code> specifying pad characters inserted before
+     * the suffix.
+     * @see #setPadPosition
+     * @see #getPadPosition
+     * @see #PAD_BEFORE_PREFIX
+     * @see #PAD_AFTER_PREFIX
+     * @see #PAD_AFTER_SUFFIX
+     * @stable ICU 2.0
+     */
+    public static final int PAD_BEFORE_SUFFIX = 2;
+
+    // [NEW]
+    /**
+     * Constant for <code>getPadPosition()</code> and
+     * <code>setPadPosition()</code> specifying pad characters inserted after
+     * the suffix.
+     * @see #setPadPosition
+     * @see #getPadPosition
+     * @see #PAD_BEFORE_PREFIX
+     * @see #PAD_AFTER_PREFIX
+     * @see #PAD_BEFORE_SUFFIX
+     * @stable ICU 2.0
+     */
+    public static final int PAD_AFTER_SUFFIX  = 3;
+
+    // Constants for characters used in programmatic (unlocalized) patterns.
+    private static final char       PATTERN_ZERO_DIGIT         = '0';
+    private static final char       PATTERN_GROUPING_SEPARATOR = ',';
+    private static final char       PATTERN_DECIMAL_SEPARATOR  = '.';
+    private static final char       PATTERN_DIGIT              = '#';
+            static final char       PATTERN_SIGNIFICANT_DIGIT  = '@';
+            static final char       PATTERN_EXPONENT           = 'E'; // [NEW]
+            static final char       PATTERN_PLUS_SIGN          = '+'; // [NEW]
+
+    // Affix
+    private static final char       PATTERN_PER_MILLE          = '\u2030';
+    private static final char       PATTERN_PERCENT            = '%';
+            static final char       PATTERN_PAD_ESCAPE         = '*'; // [NEW]
+    /*Bug 4212072
+      To meet the need of expandAffix(String, StirngBuffer)
+      [Richard/GCL]
+    */
+    private static final char       PATTERN_MINUS              = '-'; //[Richard/GCL]
+
+    // Other    
+    private static final char       PATTERN_SEPARATOR          = ';';
+
+    // Pad escape is package private to allow access by DecimalFormatSymbols.
+    // Also plus sign.  Also exponent.
+
+    /**
+     * The CURRENCY_SIGN is the standard Unicode symbol for currency.  It
+     * is used in patterns and substitued with either the currency symbol,
+     * or if it is doubled, with the international currency symbol.  If the
+     * CURRENCY_SIGN is seen in a pattern, then the decimal separator is
+     * replaced with the monetary decimal separator.
+     *
+     * The CURRENCY_SIGN is not localized.
+     */
+    private static final char       CURRENCY_SIGN = '\u00A4';
+
+    private static final char       QUOTE = '\'';
+    
+    /* Upper limit on integer and fraction digits for a Java double
+       [Richard/GCL]
+    */
+    static final int DOUBLE_INTEGER_DIGITS  = 309;
+    static final int DOUBLE_FRACTION_DIGITS = 340;
+
+    /**
+     * When someone turns on scientific mode, we assume that more than this
+     * number of digits is due to flipping from some other mode that didn't
+     * restrict the maximum, and so we force 1 integer digit.  We don't bother
+     * to track and see if someone is using exponential notation with more than
+     * this number, it wouldn't make sense anyway, and this is just to make sure
+     * that someone turning on scientific mode with default settings doesn't
+     * end up with lots of zeroes.
+     */
+    static final int MAX_SCIENTIFIC_INTEGER_DIGITS = 8;
+
+//#if defined(FOUNDATION10)
+//##    // we're not compatible with other versions, since we have no java.math.BigDecimal field
+//##    private static final long serialVersionUID = 2;
+//#else
+    // Proclaim JDK 1.1 serial compatibility.
+    private static final long serialVersionUID = 864413376551465018L;
+//#endif
+
+//#if defined(FOUNDATION10) || defined(J2SE13)
+//#else
+    private ArrayList attributes = new ArrayList();
+//#endif
+
+    /*
+     * Following are used in currency format
+     */
+/*
+    // triple currency sign char array
+    private static final char[] tripleCurrencySign = {0xA4, 0xA4, 0xA4};
+    // triple currency sign string
+    private static final String tripleCurrencyStr = new String(tripleCurrencySign);
+
+    // default currency plural pattern char array
+    private static final char[] defaultCurrencyPluralPatternChar = {0, '.', '#', '#', ' ', 0xA4, 0xA4, 0xA4};
+    // default currency plural pattern string
+    private static final String defaultCurrencyPluralPattern = new String(defaultCurrencyPluralPatternChar);
+*/
+
+    // pattern used in this formatter
+    private String formatPattern = "";
+    // style is only valid when decimal formatter is constructed by
+    // DecimalFormat(pattern, decimalFormatSymbol, style)
+    private int style = NumberFormat.NUMBERSTYLE;
+    /*
+     * Represents whether this is a currency format, and which
+     * currency format style.
+     * 0: not currency format type;
+     * 1: currency style -- symbol name, such as "$" for US dollar.
+     * 2: currency style -- ISO name, such as USD for US dollar.
+     * 3: currency style -- plural long name, such as "US Dollar" for
+     *                      "1.00 US Dollar", or "US Dollars" for
+     *                      "3.00 US Dollars".
+     */
+    private int currencySignCount = 0;
+
+
+    /* For parsing purose,
+     * Need to remember all prefix patterns and suffix patterns of 
+     * every currency format pattern, 
+     * including the pattern of default currecny style, ISO currency style,
+     * and plural currency style. And the patterns are set through applyPattern.
+     * Following are used to represent the affix patterns in currency plural
+     * formats.
+     */
+    private static final class AffixForCurrency {
+        // negative prefix pattern
+        private String negPrefixPatternForCurrency = null; 
+        // negative suffix pattern
+        private String negSuffixPatternForCurrency = null; 
+        // positive prefix pattern
+        private String posPrefixPatternForCurrency = null; 
+        // positive suffix pattern
+        private String posSuffixPatternForCurrency = null; 
+        private int patternType;
+        
+        public AffixForCurrency() { 
+            patternType = Currency.SYMBOL_NAME; 
+        }
+
+        public AffixForCurrency(String negPrefix, String negSuffix,
+                                String posPrefix, String posSuffix,
+                                int type) {
+            negPrefixPatternForCurrency = negPrefix;
+            negSuffixPatternForCurrency = negSuffix;
+            posPrefixPatternForCurrency = posPrefix;
+            posSuffixPatternForCurrency = posSuffix;
+            patternType = type;
+        }
+
+        public String getNegPrefix() {
+            return negPrefixPatternForCurrency;
+        }
+
+        public String getNegSuffix() {
+            return negSuffixPatternForCurrency;
+        }
+
+        public String getPosPrefix() {
+            return posPrefixPatternForCurrency;
+        }
+
+        public String getPosSuffix() {
+            return posSuffixPatternForCurrency;
+        }
+
+        public int getPatternType() {
+            return patternType;
+        }
+    }
+    // Affix patter set for currency.
+    // It is a set of AffixForCurrency,
+    // each element of the set saves the negative prefix,
+    // negative suffix, positive prefix, and positive suffix of a pattern.
+    private transient Set affixPatternsForCurrency = null;
+
+    // For currency parsing, since currency parsing need to parse
+    // against all currency patterns, before the parsing, need to set up 
+    // the affix patterns for currency.
+    private transient boolean isReadyForParsing = false;
+
+    // Information needed for DecimalFormat to format/parse currency plural.
+    private CurrencyPluralInfo currencyPluralInfo = null;
+
+}
+
+//eof