/*
 *******************************************************************************
 * Copyright (C) 1996-2012, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.text;

import java.math.BigInteger;
import java.text.AttributedCharacterIterator;
import java.text.AttributedCharacterIterator.Attribute;
import java.text.AttributedString;
import java.text.CharacterIterator;
import java.text.FieldPosition;
import java.text.ParsePosition;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;

import com.ibm.icu.math.BigDecimal;
import com.ibm.icu.util.Currency;
import com.ibm.icu.util.ULocale;
import com.ibm.icu.util.ULocale.Category;

/**
 * {@icuenhanced java.text.DecimalFormat}.{@icu _usage_}
 *
 * <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>
 *
 * Print out a number using the localized number, currency, and percent
 * format for each locale.
 *
 * <blockquote><pre>
 * 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).<br/>
 * Print out a number using the localized number, currency, percent,
 * scientific, integer, iso currency, and plural currency format for each locale.
 *
 * <blockquote><pre>
 * 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>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 {

    private static final long serialVersionUID = 1L;
    /**
     * @internal
     * @param delegate the NumberFormat to which to delegate
     */
    public DecimalFormat(java.text.DecimalFormat delegate) {
        super(delegate);
    }

    /**
     * Creates 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() {
        // There is no way to construct java.text.DecimalFormat with an
        // explicit Locale.
        this(new java.text.DecimalFormat());

        if (!ULocale.getDefault(Category.FORMAT).toLocale().equals(Locale.getDefault())) {
            // On Java 6 or older JRE, ULocale's FORMAT default might be different
            // from the locale used for constructing java.text.DecimalFormat
            java.text.NumberFormat jdkNfmt = java.text.NumberFormat.getInstance(ULocale.getDefault(Category.FORMAT).toLocale());
            if (jdkNfmt instanceof java.text.DecimalFormat) {
                ((java.text.DecimalFormat)numberFormat).applyPattern(((java.text.DecimalFormat)jdkNfmt).toPattern());
                ((java.text.DecimalFormat)numberFormat).setDecimalFormatSymbols(((java.text.DecimalFormat)jdkNfmt).getDecimalFormatSymbols());
            }
        }
    }

    /**
     * Creates 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.
     * @throws 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) {
        this(new java.text.DecimalFormat(
                pattern,
                new java.text.DecimalFormatSymbols(ULocale.getDefault(Category.FORMAT).toLocale())));
    }

    /**
     * Creates 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) {
        this(new java.text.DecimalFormat(pattern, symbols.dfs));
    }

//    /**
//     * Creates 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.
//     *
//     * @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;
//     * @stable ICU 4.2
//     */
//    public DecimalFormat(String pattern, DecimalFormatSymbols symbols, CurrencyPluralInfo infoInput,
//                         int style) {
//        throw new UnsupportedOperationException("Constructor not supported by com.ibm.icu.base");
//    }

    /**
     * {@inheritDoc}
     * @stable ICU 2.0
     */
    public StringBuffer format(double number, StringBuffer result, FieldPosition fieldPosition) {
        return super.format(number, result, fieldPosition);
    }

    /**
     * @stable ICU 2.0
     */
    // [Spark/CDL] Delegate to format_long_StringBuffer_FieldPosition_boolean
    public StringBuffer format(long number, StringBuffer result, FieldPosition fieldPosition) {
        return super.format(number, result, fieldPosition);
    }

    /**
     * Formats a BigInteger number.
     *
     * @stable ICU 2.0
     */
    public StringBuffer format(BigInteger number, StringBuffer result,
                               FieldPosition fieldPosition) {
        return super.format(number, result, fieldPosition);
    }

    /**
     * Formats a BigDecimal number.
     *
     * @stable ICU 2.0
     */
    public StringBuffer format(java.math.BigDecimal number, StringBuffer result,
                               FieldPosition fieldPosition) {
        return super.format(number, result, fieldPosition);
    }

    /**
     * Formats a BigDecimal number.
     *
     * @stable ICU 2.0
     */
    public StringBuffer format(BigDecimal number, StringBuffer result,
                               FieldPosition fieldPosition) {
        return super.format(number, result, fieldPosition);
    }

    /**
     * Parses 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 super.parse(text, parsePosition);
    }

//    /**
//     * 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
//     */
//    CurrencyAmount parseCurrency(String text, ParsePosition pos) {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

    /**
     * Returns a copy of the decimal format symbols used by this format.
     *
     * @return desired DecimalFormatSymbols
     * @see DecimalFormatSymbols
     * @stable ICU 2.0
     */
    public DecimalFormatSymbols getDecimalFormatSymbols() {
        return new DecimalFormatSymbols(((java.text.DecimalFormat)numberFormat).getDecimalFormatSymbols());
    }

    /**
     * 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) {
        ((java.text.DecimalFormat)numberFormat).setDecimalFormatSymbols(newSymbols.dfs);
    }

    /**
     * Returns the positive prefix.
     *
     * <p>Examples: +123, $123, sFr123
     * @return the prefix
     * @stable ICU 2.0
     */
    public String getPositivePrefix() {
        return ((java.text.DecimalFormat)numberFormat).getPositivePrefix();
    }

    /**
     * Sets the positive prefix.
     *
     * <p>Examples: +123, $123, sFr123
     * @param newValue the prefix
     * @stable ICU 2.0
     */
    public void setPositivePrefix(String newValue) {
        ((java.text.DecimalFormat)numberFormat).setPositivePrefix(newValue);
    }

    /**
     * Returns the negative prefix.
     *
     * <p>Examples: -123, ($123) (with negative suffix), sFr-123
     *
     * @return the prefix
     * @stable ICU 2.0
     */
    public String getNegativePrefix() {
        return ((java.text.DecimalFormat)numberFormat).getNegativePrefix();
    }

    /**
     * Sets the negative prefix.
     *
     * <p>Examples: -123, ($123) (with negative suffix), sFr-123
     * @param newValue the prefix
     * @stable ICU 2.0
     */
    public void setNegativePrefix(String newValue) {
        ((java.text.DecimalFormat)numberFormat).setNegativePrefix(newValue);
    }

    /**
     * Returns the positive suffix.
     *
     * <p>Example: 123%
     *
     * @return the suffix
     * @stable ICU 2.0
     */
    public String getPositiveSuffix() {
        return ((java.text.DecimalFormat)numberFormat).getPositiveSuffix();
    }

    /**
     * Sets the positive suffix.
     *
     * <p>Example: 123%
     * @param newValue the suffix
     * @stable ICU 2.0
     */
    public void setPositiveSuffix(String newValue) {
        ((java.text.DecimalFormat)numberFormat).setPositiveSuffix(newValue);
    }

    /**
     * Returns the negative suffix.
     *
     * <p>Examples: -123%, ($123) (with positive suffixes)
     *
     * @return the suffix
     * @stable ICU 2.0
     */
    public String getNegativeSuffix() {
        return ((java.text.DecimalFormat)numberFormat).getNegativeSuffix();
    }

    /**
     * Sets the positive suffix.
     *
     * <p>Examples: 123%
     * @param newValue the suffix
     * @stable ICU 2.0
     */
    public void setNegativeSuffix(String newValue) {
        ((java.text.DecimalFormat)numberFormat).setNegativeSuffix(newValue);
    }

    /**
     * Returns 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
     *
     * @return the multiplier
     * @stable ICU 2.0
     */
    public int getMultiplier() {
        return ((java.text.DecimalFormat)numberFormat).getMultiplier();
    }

    /**
     * Sets 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
     *
     * @param newValue the multiplier
     * @stable ICU 2.0
     */
    public void setMultiplier(int newValue) {
        ((java.text.DecimalFormat)numberFormat).setMultiplier(newValue);
    }

//    /**
//     * {@icu} Returns 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
//     */
//    public BigDecimal getRoundingIncrement() {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * {@icu} Sets 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.
//     * @throws 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) {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * {@icu} Sets 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.
//     * @throws IllegalArgumentException if <code>newValue</code> is < 0.0
//     * @see #getRoundingIncrement
//     * @see #getRoundingMode
//     * @see #setRoundingMode
//     * @stable ICU 3.6
//     */
//    public void setRoundingIncrement(BigDecimal newValue) {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * {@icu} Sets the rounding increment. This method also controls whether rounding is
//     * enabled.
//     *
//     * @param newValue A positive rounding increment, or 0.0 to disable rounding.
//     * @throws IllegalArgumentException if <code>newValue</code> is < 0.0
//     * @see #getRoundingIncrement
//     * @see #getRoundingMode
//     * @see #setRoundingMode
//     * @stable ICU 2.0
//     */
//    public void setRoundingIncrement(double newValue) {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * Returns 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() {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * Sets 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) {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * Returns 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() {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * Sets 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) {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * {@icu} Returns 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() {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * {@icu} Sets 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) {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * {@icu} Returns 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() {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * {@icu} Sets 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) {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * {@icu} Returns 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() {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * {@icu} Sets 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) {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * {@icu} Returns 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() {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * {@icu} Sets 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) {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * {@icu} Returns 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() {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * {@icu} Sets 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) {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

    /**
     * Returns 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 ((java.text.DecimalFormat)numberFormat).getGroupingSize();
    }

    /**
     * Sets 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) {
        ((java.text.DecimalFormat)numberFormat).setGroupingSize(newValue);
    }

//    /**
//     * {@icu} Returns 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() {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * {@icu} Sets 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) {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * {@icu} Returns the MathContext used by this format.
//     *
//     * @return desired MathContext
//     * @see #getMathContext
//     * @stable ICU 4.2
//     */
//    public MathContext getMathContextICU() {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * {@icu} Returns the MathContext used by this format.
//     *
//     * @return desired MathContext
//     * @see #getMathContext
//     * @stable ICU 4.2
//     */
//    public java.math.MathContext getMathContext() {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * {@icu} Sets the MathContext used by this format.
//     *
//     * @param newValue desired MathContext
//     * @see #getMathContext
//     * @stable ICU 4.2
//     */
//    public void setMathContextICU(MathContext newValue) {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * {@icu} Sets the MathContext used by this format.
//     *
//     * @param newValue desired MathContext
//     * @see #getMathContext
//     * @stable ICU 4.2
//     */
//    public void setMathContext(java.math.MathContext newValue) {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

    /**
     * Returns 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 ((java.text.DecimalFormat)numberFormat).isDecimalSeparatorAlwaysShown();
    }

    /**
     * Sets 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) {
        ((java.text.DecimalFormat)numberFormat).setDecimalSeparatorAlwaysShown(newValue);
    }

//    /**
//     * {@icu} 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
//     * @stable ICU 4.2
//     */
//    public CurrencyPluralInfo getCurrencyPluralInfo() {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * {@icu} Sets the CurrencyPluralInfo used by this format. The format uses a copy of
//     * the provided information.
//     *
//     * @param newInfo desired CurrencyPluralInfo
//     * @see CurrencyPluralInfo
//     * @stable ICU 4.2
//     */
//    public void setCurrencyPluralInfo(CurrencyPluralInfo newInfo) {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

    /**
     * Overrides clone.
     * @stable ICU 2.0
     */
    public Object clone() {
        return new DecimalFormatSymbols((java.text.DecimalFormatSymbols)numberFormat.clone());
    }

    /**
     * Overrides equals.
     * @stable ICU 2.0
     */
    public boolean equals(Object obj) {
        return super.equals(obj);
    }

    /**
     * Overrides hashCode.
     * @stable ICU 2.0
     */
    public int hashCode() {
        return super.hashCode();
    }

    /**
     * Synthesizes a pattern string that represents the current state of this Format
     * object.
     *
     * @see #applyPattern
     * @stable ICU 2.0
     */
    public String toPattern() {
        return ((java.text.DecimalFormat)numberFormat).toPattern();
    }

    /**
     * Synthesizes a localized pattern string that represents the current state of this
     * Format object.
     *
     * @see #applyPattern
     * @stable ICU 2.0
     */
    public String toLocalizedPattern() {
        return ((java.text.DecimalFormat)numberFormat).toLocalizedPattern();
    }

    /**
     * Formats the object to an attributed string, and return the corresponding iterator.
     *
     * @stable ICU 3.6
     */
    public AttributedCharacterIterator formatToCharacterIterator(Object obj) {
        AttributedCharacterIterator it = numberFormat.formatToCharacterIterator(obj);

        // Extract formatted String first
        StringBuilder sb = new StringBuilder();
        for (char c = it.first(); c != CharacterIterator.DONE; c = it.next()) {
            sb.append(c);
        }

        // Create AttributedString
        AttributedString attrstr = new AttributedString(sb.toString());

        // Map JDK Field to ICU Field
        int idx = 0;
        it.first();
        while (idx < it.getEndIndex()) {
            int end = it.getRunLimit();
            Map<Attribute, Object> attributes = it.getAttributes();
            if (attributes != null) {
                for (Entry<Attribute, Object> entry : attributes.entrySet()) {
                    Attribute attr = entry.getKey();
                    Object val = entry.getValue();
                    if (attr.equals(java.text.NumberFormat.Field.CURRENCY)) {
                        val = attr = Field.CURRENCY;
                    } else if (attr.equals(java.text.NumberFormat.Field.DECIMAL_SEPARATOR)) {
                        val = attr = Field.DECIMAL_SEPARATOR;
                    } else if (attr.equals(java.text.NumberFormat.Field.EXPONENT)) {
                        val = attr = Field.EXPONENT;
                    } else if (attr.equals(java.text.NumberFormat.Field.EXPONENT_SIGN)) {
                        val = attr = Field.EXPONENT_SIGN;
                    } else if (attr.equals(java.text.NumberFormat.Field.EXPONENT_SYMBOL)) {
                        val = attr = Field.EXPONENT_SYMBOL;
                    } else if (attr.equals(java.text.NumberFormat.Field.FRACTION)) {
                        val = attr = Field.FRACTION;
                    } else if (attr.equals(java.text.NumberFormat.Field.GROUPING_SEPARATOR)) {
                        val = attr = Field.GROUPING_SEPARATOR;
                    } else if (attr.equals(java.text.NumberFormat.Field.INTEGER)) {
                        val = attr = Field.INTEGER;
                    } else if (attr.equals(java.text.NumberFormat.Field.PERCENT)) {
                        val = attr = Field.PERCENT;
                    } else if (attr.equals(java.text.NumberFormat.Field.PERMILLE)) {
                        val = attr = Field.PERMILLE;
                    } else if (attr.equals(java.text.NumberFormat.Field.SIGN)) {
                        val = attr = Field.SIGN;
                    }
                    attrstr.addAttribute(attr, val, idx, end);
                }
            }
            idx = end;
            while (it.getIndex() < idx) {
                it.next();
            }
        }

        return attrstr.getIterator();
    }

    /**
     * Applies 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) {
        ((java.text.DecimalFormat)numberFormat).applyPattern(pattern);
    }

    /**
     * Applies 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) {
        ((java.text.DecimalFormat)numberFormat).applyLocalizedPattern(pattern);
    }

    /**
     * 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(newValue);
    }

    /**
     * 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(newValue);
    }

//    /**
//     * {@icu} Returns the minimum number of significant digits that will be
//     * displayed. This value has no effect unless {@link #areSignificantDigitsUsed()}
//     * returns true.
//     *
//     * @return the fewest significant digits that will be shown
//     * @stable ICU 3.0
//     */
//    public int getMinimumSignificantDigits() {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * {@icu} Returns the maximum number of significant digits that will be
//     * displayed. This value has no effect unless {@link #areSignificantDigitsUsed()}
//     * returns true.
//     *
//     * @return the most significant digits that will be shown
//     * @stable ICU 3.0
//     */
//    public int getMaximumSignificantDigits() {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * {@icu} 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 {@link #areSignificantDigitsUsed()}
//     * returns true.
//     *
//     * @param min the fewest significant digits to be shown
//     * @stable ICU 3.0
//     */
//    public void setMinimumSignificantDigits(int min) {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * {@icu} 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 {@link #areSignificantDigitsUsed()}
//     * returns true.
//     *
//     * @param max the most significant digits to be shown
//     * @stable ICU 3.0
//     */
//    public void setMaximumSignificantDigits(int max) {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * {@icu} 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() {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

//    /**
//     * {@icu} 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) {
//        throw new UnsupportedOperationException("Method not supported by com.ibm.icu.base");
//    }

    /**
     * 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) {
        super.setCurrency(theCurrency);
    }

    /**
     * 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(newValue);
    }

    /**
     * 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(newValue);
    }

    /**
     * Sets whether {@link #parse(String, ParsePosition)} returns BigDecimal. The
     * default value is false.
     *
     * @param value true if {@link #parse(String, ParsePosition)}
     * returns BigDecimal.
     * @stable ICU 3.6
     */
    public void setParseBigDecimal(boolean value) {
        ((java.text.DecimalFormat)numberFormat).setParseBigDecimal(value);
    }

    /**
     * Returns whether {@link #parse(String, ParsePosition)} returns BigDecimal.
     *
     * @return true if {@link #parse(String, ParsePosition)} returns BigDecimal.
     * @stable ICU 3.6
     */
    public boolean isParseBigDecimal() {
        return ((java.text.DecimalFormat)numberFormat).isParseBigDecimal();
    }

    // ----------------------------------------------------------------------
    // CONSTANTS
    // ----------------------------------------------------------------------

    /**
     * {@icu} Constant for {@link #getPadPosition()} and {@link #setPadPosition(int)} to
     * specify 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;

    /**
     * {@icu} Constant for {@link #getPadPosition()} and {@link #setPadPosition(int)} to
     * specify 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;

    /**
     * {@icu} Constant for {@link #getPadPosition()} and {@link #setPadPosition(int)} to
     * specify 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;

    /**
     * {@icu} Constant for {@link #getPadPosition()} and {@link #setPadPosition(int)} to
     * specify 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;
}

// eof
