// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
 *******************************************************************************
 * Copyright (C) 1996-2016, International Business Machines Corporation and
 * others. All Rights Reserved.
 *******************************************************************************
 */
package com.ibm.icu.text;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Locale;
import java.util.MissingResourceException;

import com.ibm.icu.impl.CacheBase;
import com.ibm.icu.impl.CurrencyData;
import com.ibm.icu.impl.CurrencyData.CurrencyDisplayInfo;
import com.ibm.icu.impl.CurrencyData.CurrencyFormatInfo;
import com.ibm.icu.impl.CurrencyData.CurrencySpacingInfo;
import com.ibm.icu.impl.ICUData;
import com.ibm.icu.impl.ICUResourceBundle;
import com.ibm.icu.impl.SoftCache;
import com.ibm.icu.impl.UResource;
import com.ibm.icu.util.Currency;
import com.ibm.icu.util.ICUCloneNotSupportedException;
import com.ibm.icu.util.ULocale;
import com.ibm.icu.util.ULocale.Category;
import com.ibm.icu.util.UResourceBundle;

/**
 * {@icuenhanced java.text.DecimalFormatSymbols}.{@icu _usage_}
 *
 * This class represents the set of symbols (such as the decimal separator, the grouping
 * separator, and so on) needed by <code>DecimalFormat</code> to format
 * numbers. <code>DecimalFormat</code> creates for itself an instance of
 * <code>DecimalFormatSymbols</code> from its locale data.  If you need to change any of
 * these symbols, you can get the <code>DecimalFormatSymbols</code> object from your
 * <code>DecimalFormat</code> and modify it.
 *
 * @see          java.util.Locale
 * @see          DecimalFormat
 * @author       Mark Davis
 * @author       Alan Liu
 * @stable ICU 2.0
 */
public class DecimalFormatSymbols implements Cloneable, Serializable {
    /**
     * Creates a DecimalFormatSymbols object for the default <code>FORMAT</code> locale.
     * @see Category#FORMAT
     * @stable ICU 2.0
     */
    public DecimalFormatSymbols() {
        initialize(ULocale.getDefault(Category.FORMAT));
    }

    /**
     * Creates a DecimalFormatSymbols object for the given locale.
     * @param locale the locale
     * @stable ICU 2.0
     */
    public DecimalFormatSymbols(Locale locale) {
        initialize(ULocale.forLocale(locale));
    }

    /**
     * {@icu} Creates a DecimalFormatSymbols object for the given locale.
     * @param locale the locale
     * @stable ICU 3.2
     */
    public DecimalFormatSymbols(ULocale locale) {
        initialize(locale);
    }

    /**
     * Returns a DecimalFormatSymbols instance for the default locale.
     *
     * <p><strong>Note:</strong> Unlike
     * <code>java.text.DecimalFormatSymbols#getInstance</code>, this method simply returns
     * <code>new com.ibm.icu.text.DecimalFormatSymbols()</code>.  ICU currently does not
     * support <code>DecimalFormatSymbolsProvider</code>, which was introduced in Java 6.
     *
     * @return A DecimalFormatSymbols instance.
     * @stable ICU 3.8
     */
    public static DecimalFormatSymbols getInstance() {
        return new DecimalFormatSymbols();
    }

    /**
     * Returns a DecimalFormatSymbols instance for the given locale.
     *
     * <p><strong>Note:</strong> Unlike
     * <code>java.text.DecimalFormatSymbols#getInstance</code>, this method simply returns
     * <code>new com.ibm.icu.text.DecimalFormatSymbols(locale)</code>.  ICU currently does
     * not support <code>DecimalFormatSymbolsProvider</code>, which was introduced in Java
     * 6.
     *
     * @param locale the locale.
     * @return A DecimalFormatSymbols instance.
     * @stable ICU 3.8
     */
    public static DecimalFormatSymbols getInstance(Locale locale) {
        return new DecimalFormatSymbols(locale);
    }

    /**
     * Returns a DecimalFormatSymbols instance for the given locale.
     *
     * <p><strong>Note:</strong> Unlike
     * <code>java.text.DecimalFormatSymbols#getInstance</code>, this method simply returns
     * <code>new com.ibm.icu.text.DecimalFormatSymbols(locale)</code>.  ICU currently does
     * not support <code>DecimalFormatSymbolsProvider</code>, which was introduced in Java
     * 6.
     *
     * @param locale the locale.
     * @return A DecimalFormatSymbols instance.
     * @stable ICU 3.8
     */
    public static DecimalFormatSymbols getInstance(ULocale locale) {
        return new DecimalFormatSymbols(locale);
    }

    /**
     * Returns an array of all locales for which the <code>getInstance</code> methods of
     * this class can return localized instances.
     *
     * <p><strong>Note:</strong> Unlike
     * <code>java.text.DecimalFormatSymbols#getAvailableLocales</code>, this method simply
     * returns the array of <code>Locale</code>s available for this class.  ICU currently
     * does not support <code>DecimalFormatSymbolsProvider</code>, which was introduced in
     * Java 6.
     *
     * @return An array of <code>Locale</code>s for which localized
     * <code>DecimalFormatSymbols</code> instances are available.
     * @stable ICU 3.8
     */
    public static Locale[] getAvailableLocales() {
        return ICUResourceBundle.getAvailableLocales();
    }

    /**
     * {@icu} Returns an array of all locales for which the <code>getInstance</code>
     * methods of this class can return localized instances.
     *
     * <p><strong>Note:</strong> Unlike
     * <code>java.text.DecimalFormatSymbols#getAvailableLocales</code>, this method simply
     * returns the array of <code>ULocale</code>s available in this class.  ICU currently
     * does not support <code>DecimalFormatSymbolsProvider</code>, which was introduced in
     * Java 6.
     *
     * @return An array of <code>ULocale</code>s for which localized
     * <code>DecimalFormatSymbols</code> instances are available.
     * @stable ICU 3.8 (retain)
     * @provisional This API might change or be removed in a future release.
     */
    public static ULocale[] getAvailableULocales() {
        return ICUResourceBundle.getAvailableULocales();
    }


    /**
     * Returns the character used for zero. Different for Arabic, etc.
     * @return the character
     * @stable ICU 2.0
     * @discouraged ICU 58 use {@link #getDigitStrings()} instead.
     */
    public char getZeroDigit() {
        return zeroDigit;
    }

    /**
     * Returns the array of characters used as digits, in order from 0 through 9
     * @return The array
     * @stable ICU 4.6
     * @see #getDigitStrings()
     * @discouraged ICU 58 use {@link #getDigitStrings()} instead.
     */
    public char[] getDigits() {
        return digits.clone();
    }

    /**
     * Sets the character used for zero.
     * <p>
     * <b>Note:</b> When the specified zeroDigit is a Unicode decimal digit character
     * (category:Nd) and the number value is 0, then this method propagate digit 1 to
     * digit 9 by incrementing code point one by one.
     *
     * @param zeroDigit the zero character.
     * @stable ICU 2.0
     * @discouraged ICU 58 use {@link #setDigitStrings(String[])} instead.
     */
    public void setZeroDigit(char zeroDigit) {
        this.zeroDigit = zeroDigit;

        // digitStrings or digits might be referencing a cached copy for
        // optimization purpose, so creating a copy before making a modification
        digitStrings = digitStrings.clone();
        digits = digits.clone();

        // Make digitStrings field and digits field in sync
        digitStrings[0] = String.valueOf(zeroDigit);
        digits[0] = zeroDigit;

        // Propagate digit 1 - 9 only when the input zeroDigit is a
        // Unicode number and its integer value is 0.

        if (Character.digit(zeroDigit, 10) == 0) {
            for (int i = 1; i < 10; i++) {
                char d = (char)(zeroDigit + i);
                digitStrings[i] = String.valueOf(d);
                digits[i] = d;
            }
        }
    }

    /**
    * {@icu} Returns the array of strings used as digits, in order from 0 through 9
    * @return The array of ten digit strings
    * @see #setDigitStrings(String[])
    * @draft ICU 58
    * @provisional This API might change or be removed in a future release.
    */
    public String[] getDigitStrings() {
        return digitStrings.clone();
    }

    /**
     * Returns the array of strings used as digits, in order from 0 through 9
     * Package private method - doesn't create a defensively copy.
     * @return the array of digit strings
     */
    String[] getDigitStringsLocal() {
        return digitStrings;
    }

    /**
    * {@icu} Sets the array of strings used as digits, in order from 0 through 9
    * <p>
    * <b>Note:</b>
    * <p>
    * When the input array of digit strings contains any strings
    * represented by multiple Java chars, then {@link #getDigits()} will return
    * the default digits ('0' - '9') and {@link #getZeroDigit()} will return the
    * default zero digit ('0').
    *
    * @param digitStrings The array of digit strings. The length of the array must be exactly 10.
    * @throws NullPointerException if the <code>digitStrings</code> is null.
    * @throws IllegalArgumentException if the length of the array is not 10.
    * @see #getDigitStrings()
    * @draft ICU 58
    * @provisional This API might change or be removed in a future release.
    */
    public void setDigitStrings(String[] digitStrings) {
        if (digitStrings == null) {
            throw new NullPointerException("The input digit string array is null");
        }
        if (digitStrings.length != 10) {
            throw new IllegalArgumentException("Number of digit strings is not 10");
        }

        // Scan input array and create char[] representation if possible
        String[] tmpDigitStrings = new String[10];
        char[] tmpDigits = new char[10];
        for (int i = 0; i < 10; i++) {
            if (digitStrings[i] == null) {
                throw new IllegalArgumentException("The input digit string array contains a null element");
            }
            tmpDigitStrings[i] = digitStrings[i];
            if (tmpDigits != null && digitStrings[i].length() == 1) {
                tmpDigits[i] = digitStrings[i].charAt(0);
            } else {
                // contains digit string with multiple UTF-16 code units
                tmpDigits = null;
            }
        }

        this.digitStrings = tmpDigitStrings;

        if (tmpDigits == null) {
            // fallback to the default digit chars
            this.zeroDigit = DEF_DIGIT_CHARS_ARRAY[0];
            this.digits = DEF_DIGIT_CHARS_ARRAY;
        } else {
            this.zeroDigit = tmpDigits[0];
            this.digits = tmpDigits;
        }
    }

    /**
     * Returns the character used to represent a significant digit in a pattern.
     * @return the significant digit pattern character
     * @stable ICU 3.0
     */
    public char getSignificantDigit() {
        return sigDigit;
    }

    /**
     * Sets the character used to represent a significant digit in a pattern.
     * @param sigDigit the significant digit pattern character
     * @stable ICU 3.0
     */
    public void setSignificantDigit(char sigDigit) {
        this.sigDigit = sigDigit;
    }

    /**
     * Returns the character used for grouping separator. Different for French, etc.
     * @return the thousands character
     * @stable ICU 2.0
     * @discouraged ICU 58 use {@link #getGroupingSeparatorString()} instead.
     */
    public char getGroupingSeparator() {
        return groupingSeparator;
    }

    /**
     * Sets the character used for grouping separator. Different for French, etc.
     * @param groupingSeparator the thousands character
     * @stable ICU 2.0
     * @see #setGroupingSeparatorString(String)
     */
    public void setGroupingSeparator(char groupingSeparator) {
        this.groupingSeparator = groupingSeparator;
        this.groupingSeparatorString = String.valueOf(groupingSeparator);
    }

    /**
     * {@icu} Returns the string used for grouping separator. Different for French, etc.
     * @return the grouping separator string
     * @see #setGroupingSeparatorString(String)
     * @draft ICU 58
     * @provisional This API might change or be removed in a future release.
     */
    public String getGroupingSeparatorString() {
        return groupingSeparatorString;
    }

    /**
     * {@icu} Sets the string used for grouping separator.
     * <p>
     * <b>Note:</b> When the input grouping separator String is represented
     * by multiple Java chars, then {@link #getGroupingSeparator()} will
     * return the default grouping separator character (',').
     *
     * @param groupingSeparatorString the grouping separator string
     * @throws NullPointerException if <code>groupingSeparatorString</code> is null.
     * @see #getGroupingSeparatorString()
     * @draft ICU 58
     * @provisional This API might change or be removed in a future release.
     */
    public void setGroupingSeparatorString(String groupingSeparatorString) {
        if (groupingSeparatorString == null) {
            throw new NullPointerException("The input grouping separator is null");
        }
        this.groupingSeparatorString = groupingSeparatorString;
        if (groupingSeparatorString.length() == 1) {
            this.groupingSeparator = groupingSeparatorString.charAt(0);
        } else {
            // Use the default grouping separator character as fallback
            this.groupingSeparator = DEF_GROUPING_SEPARATOR;
        }
    }

    /**
     * Returns the character used for decimal sign. Different for French, etc.
     * @return the decimal character
     * @stable ICU 2.0
     * @discouraged ICU 58 use {@link #getDecimalSeparatorString()} instead.
     */
    public char getDecimalSeparator() {
        return decimalSeparator;
    }

    /**
     * Sets the character used for decimal sign. Different for French, etc.
     * @param decimalSeparator the decimal character
     * @stable ICU 2.0
     */
    public void setDecimalSeparator(char decimalSeparator) {
        this.decimalSeparator = decimalSeparator;
        this.decimalSeparatorString = String.valueOf(decimalSeparator);
    }

    /**
     * {@icu} Returns the string used for decimal sign.
     * @return the decimal sign string
     * @see #setDecimalSeparatorString(String)
     * @draft ICU 58
     * @provisional This API might change or be removed in a future release.
     */
    public String getDecimalSeparatorString() {
        return decimalSeparatorString;
    }

    /**
     * {@icu} Sets the string used for decimal sign.
     * <p>
     * <b>Note:</b> When the input decimal separator String is represented
     * by multiple Java chars, then {@link #getDecimalSeparator()} will
     * return the default decimal separator character ('.').
     *
     * @param decimalSeparatorString the decimal sign string
     * @throws NullPointerException if <code>decimalSeparatorString</code> is null.
     * @see #getDecimalSeparatorString()
     * @draft ICU 58
     * @provisional This API might change or be removed in a future release.
     */
    public void setDecimalSeparatorString(String decimalSeparatorString) {
        if (decimalSeparatorString == null) {
            throw new NullPointerException("The input decimal separator is null");
        }
        this.decimalSeparatorString = decimalSeparatorString;
        if (decimalSeparatorString.length() == 1) {
            this.decimalSeparator = decimalSeparatorString.charAt(0);
        } else {
            // Use the default decimal separator character as fallback
            this.decimalSeparator = DEF_DECIMAL_SEPARATOR;
        }
    }

    /**
     * Returns the character used for mille percent sign. Different for Arabic, etc.
     * @return the mille percent character
     * @stable ICU 2.0
     * @discouraged ICU 58 use {@link #getPerMillString()} instead.
     */
    public char getPerMill() {
        return perMill;
    }

    /**
     * Sets the character used for mille percent sign. Different for Arabic, etc.
     * @param perMill the mille percent character
     * @stable ICU 2.0
     */
    public void setPerMill(char perMill) {
        this.perMill = perMill;
        this.perMillString = String.valueOf(perMill);
    }

    /**
     * {@icu} Returns the string used for permille sign.
     * @return the permille string
     * @see #setPerMillString(String)
     * @draft ICU 58
     * @provisional This API might change or be removed in a future release.
     */
    public String getPerMillString() {
        return perMillString;
    }

    /**
    * {@icu} Sets the string used for permille sign.
     * <p>
     * <b>Note:</b> When the input permille String is represented
     * by multiple Java chars, then {@link #getPerMill()} will
     * return the default permille character ('&#x2030;').
     *
     * @param perMillString the permille string
     * @throws NullPointerException if <code>perMillString</code> is null.
     * @see #getPerMillString()
     * @draft ICU 58
     * @provisional This API might change or be removed in a future release.
     */
    public void setPerMillString(String perMillString) {
        if (perMillString == null) {
            throw new NullPointerException("The input permille string is null");
        }
        this.perMillString = perMillString;
        if (perMillString.length() == 1) {
            this.perMill = perMillString.charAt(0);
        } else {
            // Use the default permille character as fallback
            this.perMill = DEF_PERMILL;
        }
    }

    /**
     * Returns the character used for percent sign. Different for Arabic, etc.
     * @return the percent character
     * @stable ICU 2.0
     * @discouraged ICU 58 use {@link #getPercentString()} instead.
     */
    public char getPercent() {
        return percent;
    }

    /**
     * Sets the character used for percent sign. Different for Arabic, etc.
     * @param percent the percent character
     * @stable ICU 2.0
     */
    public void setPercent(char percent) {
        this.percent = percent;
        this.percentString = String.valueOf(percent);
    }

    /**
     * {@icu} Returns the string used for percent sign.
     * @return the percent string
     * @see #setPercentString(String)
     * @draft ICU 58
     * @provisional This API might change or be removed in a future release.
     */
    public String getPercentString() {
        return percentString;
    }

    /**
     * {@icu} Sets the string used for percent sign.
     * <p>
     * <b>Note:</b> When the input grouping separator String is represented
     * by multiple Java chars, then {@link #getPercent()} will
     * return the default percent sign character ('%').
     *
     * @param percentString the percent string
     * @throws NullPointerException if <code>percentString</code> is null.
     * @see #getPercentString()
     * @draft ICU 58
     * @provisional This API might change or be removed in a future release.
     */
    public void setPercentString(String percentString) {
        if (percentString == null) {
            throw new NullPointerException("The input percent sign is null");
        }
        this.percentString = percentString;
        if (percentString.length() == 1) {
            this.percent = percentString.charAt(0);
        } else {
            // Use default percent character as fallback
            this.percent = DEF_PERCENT;
        }
    }

    /**
     * Returns the character used for a digit in a pattern.
     * @return the digit pattern character
     * @stable ICU 2.0
     */
    public char getDigit() {
        return digit;
    }

    /**
     * Sets the character used for a digit in a pattern.
     * @param digit the digit pattern character
     * @stable ICU 2.0
     */
    public void setDigit(char digit) {
        this.digit = digit;
    }

    /**
     * Returns the character used to separate positive and negative subpatterns
     * in a pattern.
     * @return the pattern separator character
     * @stable ICU 2.0
     */
    public char getPatternSeparator() {
        return patternSeparator;
    }

    /**
     * Sets the character used to separate positive and negative subpatterns
     * in a pattern.
     * @param patternSeparator the pattern separator character
     * @stable ICU 2.0
     */
    public void setPatternSeparator(char patternSeparator) {
        this.patternSeparator = patternSeparator;
    }

    /**
     * Returns the String used to represent infinity. Almost always left
     * unchanged.
     * @return the Infinity string
     * @stable ICU 2.0
     */
     //Bug 4194173 [Richard/GCL]

    public String getInfinity() {
        return infinity;
    }

    /**
     * Sets the String used to represent infinity. Almost always left
     * unchanged.
     * @param infinity the Infinity String
     * @stable ICU 2.0
     */
    public void setInfinity(String infinity) {
        this.infinity = infinity;
    }

    /**
     * Returns the String used to represent NaN. Almost always left
     * unchanged.
     * @return the NaN String
     * @stable ICU 2.0
     */
     //Bug 4194173 [Richard/GCL]
    public String getNaN() {
        return NaN;
    }

    /**
     * Sets the String used to represent NaN. Almost always left
     * unchanged.
     * @param NaN the NaN String
     * @stable ICU 2.0
     */
    public void setNaN(String NaN) {
        this.NaN = NaN;
    }

    /**
     * Returns the character used to represent minus sign. If no explicit
     * negative format is specified, one is formed by prefixing
     * minusSign to the positive format.
     * @return the minus sign character
     * @stable ICU 2.0
     * @discouraged ICU 58 use {@link #getMinusSignString()} instead.
     */
    public char getMinusSign() {
        return minusSign;
    }

    /**
     * Sets the character used to represent minus sign. If no explicit
     * negative format is specified, one is formed by prefixing
     * minusSign to the positive format.
     * @param minusSign the minus sign character
     * @stable ICU 2.0
     */
    public void setMinusSign(char minusSign) {
        this.minusSign = minusSign;
        this.minusString = String.valueOf(minusSign);
    }

    /**
     * {@icu} Returns the string used to represent minus sign.
     * @return the minus sign string
     * @see #setMinusSignString(String)
     * @draft ICU 58
     * @provisional This API might change or be removed in a future release.
     */
    public String getMinusSignString() {
        return minusString;
    }

    /**
     * {@icu} Sets the string used to represent minus sign.
     * <p>
     * <b>Note:</b> When the input minus sign String is represented
     * by multiple Java chars, then {@link #getMinusSign()} will
     * return the default minus sign character ('-').
     *
     * @param minusSignString the minus sign string
     * @throws NullPointerException if <code>minusSignString</code> is null.
     * @see #getGroupingSeparatorString()
     * @draft ICU 58
     * @provisional This API might change or be removed in a future release.
     */
    public void setMinusSignString(String minusSignString) {
        if (minusSignString == null) {
            throw new NullPointerException("The input minus sign is null");
        }
        this.minusString = minusSignString;
        if (minusSignString.length() == 1) {
            this.minusSign = minusSignString.charAt(0);
        } else {
            // Use the default minus sign as fallback
            this.minusSign = DEF_MINUS_SIGN;
        }
    }

    /**
     * {@icu} Returns the localized plus sign.
     * @return the plus sign, used in localized patterns and formatted
     * strings
     * @see #setPlusSign
     * @see #setMinusSign
     * @see #getMinusSign
     * @stable ICU 2.0
     * @discouraged ICU 58 use {@link #getPlusSignString()} instead.
     */
    public char getPlusSign() {
        return plusSign;
    }

    /**
     * {@icu} Sets the localized plus sign.
     * @param plus the plus sign, used in localized patterns and formatted
     * strings
     * @see #getPlusSign
     * @see #setMinusSign
     * @see #getMinusSign
     * @stable ICU 2.0
     */
    public void setPlusSign(char plus) {
        this.plusSign = plus;
        this.plusString = String.valueOf(plus);
    }

    /**
     * {@icu} Returns the string used to represent plus sign.
     * @return the plus sign string
     * @draft ICU 58
     * @provisional This API might change or be removed in a future release.
     */
    public String getPlusSignString() {
        return plusString;
    }

    /**
     * {@icu} Sets the localized plus sign string.
     * <p>
     * <b>Note:</b> When the input plus sign String is represented
     * by multiple Java chars, then {@link #getPlusSign()} will
     * return the default plus sign character ('+').
     *
     * @param plusSignString the plus sign string, used in localized patterns and formatted
     * strings
     * @throws NullPointerException if <code>plusSignString</code> is null.
     * @see #getPlusSignString()
     * @draft ICU 58
     * @provisional This API might change or be removed in a future release.
     */
    public void setPlusSignString(String plusSignString) {
        if (plusSignString == null) {
            throw new NullPointerException("The input plus sign is null");
        }
        this.plusString = plusSignString;
        if (plusSignString.length() == 1) {
            this.plusSign = plusSignString.charAt(0);
        } else {
            // Use the default plus sign as fallback
            this.plusSign = DEF_PLUS_SIGN;
        }
    }

    /**
     * Returns the string denoting the local currency.
     * @return the local currency String.
     * @stable ICU 2.0
     */
    public String getCurrencySymbol() {
        return currencySymbol;
    }

    /**
     * Sets the string denoting the local currency.
     * @param currency the local currency String.
     * @stable ICU 2.0
     */
    public void setCurrencySymbol(String currency) {
        currencySymbol = currency;
    }

    /**
     * Returns the international string denoting the local currency.
     * @return the international string denoting the local currency
     * @stable ICU 2.0
     */
    public String getInternationalCurrencySymbol() {
        return intlCurrencySymbol;
    }

    /**
     * Sets the international string denoting the local currency.
     * @param currency the international string denoting the local currency.
     * @stable ICU 2.0
     */
    public void setInternationalCurrencySymbol(String currency) {
        intlCurrencySymbol = currency;
    }

    /**
     * Returns the currency symbol, for {@link DecimalFormatSymbols#getCurrency()} API
     * compatibility only. ICU clients should use the Currency API directly.
     * @return the currency used, or null
     * @stable ICU 3.4
     */
    public Currency getCurrency() {
        return currency;
    }

    /**
     * Sets the currency.
     *
     * <p><strong>Note:</strong> ICU does not use the DecimalFormatSymbols for the currency
     * any more.  This API is present for API compatibility only.
     *
     * <p>This also sets the currency symbol attribute to the currency's symbol
     * in the DecimalFormatSymbols' locale, and the international currency
     * symbol attribute to the currency's ISO 4217 currency code.
     *
     * @param currency the new currency to be used
     * @throws NullPointerException if <code>currency</code> is null
     * @see #setCurrencySymbol
     * @see #setInternationalCurrencySymbol
     *
     * @stable ICU 3.4
     */
    public void setCurrency(Currency currency) {
        if (currency == null) {
            throw new NullPointerException();
        }
        this.currency = currency;
        intlCurrencySymbol = currency.getCurrencyCode();
        currencySymbol = currency.getSymbol(requestedLocale);
    }

    /**
     * Returns the monetary decimal separator.
     * @return the monetary decimal separator character
     * @stable ICU 2.0
     * @discouraged ICU 58 use {@link #getMonetaryDecimalSeparatorString()} instead.
     */
    public char getMonetaryDecimalSeparator() {
        return monetarySeparator;
    }

    /**
     * Sets the monetary decimal separator.
     * @param sep the monetary decimal separator character
     * @stable ICU 2.0
     */
    public void setMonetaryDecimalSeparator(char sep) {
        this.monetarySeparator = sep;
        this.monetarySeparatorString = String.valueOf(sep);
    }

    /**
     * {@icu} Returns the monetary decimal separator string.
     * @return the monetary decimal separator string
     * @see #setMonetaryDecimalSeparatorString(String)
     * @draft ICU 58
     * @provisional This API might change or be removed in a future release.
     */
    public String getMonetaryDecimalSeparatorString() {
        return monetarySeparatorString;
    }

    /**
     * {@icu} Sets the monetary decimal separator string.
     * <p>
     * <b>Note:</b> When the input monetary decimal separator String is represented
     * by multiple Java chars, then {@link #getMonetaryDecimalSeparatorString()} will
     * return the default monetary decimal separator character ('.').
     *
     * @param sep the monetary decimal separator string
     * @throws NullPointerException if <code>sep</code> is null.
     * @see #getMonetaryDecimalSeparatorString()
     * @draft ICU 58
     * @provisional This API might change or be removed in a future release.
     */
    public void setMonetaryDecimalSeparatorString(String sep) {
        if (sep == null) {
            throw new NullPointerException("The input monetary decimal separator is null");
        }
        this.monetarySeparatorString = sep;
        if (sep.length() == 1) {
            this.monetarySeparator = sep.charAt(0);
        } else {
            // Use default decimap separator character as fallbacl
            this.monetarySeparator = DEF_DECIMAL_SEPARATOR;
        }
    }

    /**
     * {@icu} Returns the monetary grouping separator.
     * @return the monetary grouping separator character
     * @stable ICU 3.6
     * @discouraged ICU 58 use {@link #getMonetaryGroupingSeparatorString()} instead.
     */
    public char getMonetaryGroupingSeparator() {
        return monetaryGroupingSeparator;
    }

    /**
     * {@icu} Sets the monetary grouping separator.
     * @param sep the monetary grouping separator character
     * @stable ICU 3.6
     */
    public void setMonetaryGroupingSeparator(char sep) {
        this.monetaryGroupingSeparator = sep;
        this.monetaryGroupingSeparatorString = String.valueOf(sep);
    }

    /**
     * {@icu} Returns the monetary grouping separator.
     * @return the monetary grouping separator string
     * @see #setMonetaryGroupingSeparatorString(String)
     * @draft ICU 58
     * @provisional This API might change or be removed in a future release.
     */
    public String getMonetaryGroupingSeparatorString() {
        return monetaryGroupingSeparatorString;
    }

    /**
     * {@icu} Sets the monetary grouping separator string.
     * <p>
     * <b>Note:</b> When the input grouping separator String is represented
     * by multiple Java chars, then {@link #getMonetaryGroupingSeparator()} will
     * return the default monetary grouping separator character (',').
     *
     * @param sep the monetary grouping separator string
     * @throws NullPointerException if <code>sep</code> is null.
     * @see #getMonetaryGroupingSeparatorString()
     * @draft ICU 58
     * @provisional This API might change or be removed in a future release.
     */
    public void setMonetaryGroupingSeparatorString(String sep) {
        if (sep == null) {
            throw new NullPointerException("The input monetary grouping separator is null");
        }
        this.monetaryGroupingSeparatorString = sep;
        if (sep.length() == 1) {
            this.monetaryGroupingSeparator = sep.charAt(0);
        } else {
            // Use default grouping separator character as fallback
            this.monetaryGroupingSeparator = DEF_GROUPING_SEPARATOR;
        }
    }

    /**
    }
     * Internal API for NumberFormat
     * @return String currency pattern string
     */
    String getCurrencyPattern() {
        return currencyPattern;
    }

    /**
    * Returns the multiplication sign
    * @stable ICU 54
    */
    public String getExponentMultiplicationSign() {
        return exponentMultiplicationSign;
    }

    /**
    * Sets the multiplication sign
    * @stable ICU 54
    */
    public void setExponentMultiplicationSign(String exponentMultiplicationSign) {
        this.exponentMultiplicationSign = exponentMultiplicationSign;
    }

    /**
     * {@icu} Returns the string used to separate the mantissa from the exponent.
     * Examples: "x10^" for 1.23x10^4, "E" for 1.23E4.
     * @return the localized exponent symbol, used in localized patterns
     * and formatted strings
     * @see #setExponentSeparator
     * @stable ICU 2.0
     */
    public String getExponentSeparator() {
        return exponentSeparator;
    }

    /**
     * {@icu} Sets the string used to separate the mantissa from the exponent.
     * Examples: "x10^" for 1.23x10^4, "E" for 1.23E4.
     * @param exp the localized exponent symbol, used in localized patterns
     * and formatted strings
     * @see #getExponentSeparator
     * @stable ICU 2.0
     */
    public void setExponentSeparator(String exp) {
        exponentSeparator = exp;
    }

    /**
     * {@icu} Returns the character used to pad numbers out to a specified width.  This is
     * not the pad character itself; rather, it is the special pattern character
     * <em>preceding</em> the pad character.  In the pattern "*_#,##0", '*' is the pad
     * escape, and '_' is the pad character.
     * @return the character
     * @see #setPadEscape
     * @see DecimalFormat#getFormatWidth
     * @see DecimalFormat#getPadPosition
     * @see DecimalFormat#getPadCharacter
     * @stable ICU 2.0
     */
    public char getPadEscape() {
        return padEscape;
    }

    /**
     * {@icu} Sets the character used to pad numbers out to a specified width.  This is not
     * the pad character itself; rather, it is the special pattern character
     * <em>preceding</em> the pad character.  In the pattern "*_#,##0", '*' is the pad
     * escape, and '_' is the pad character.
     * @see #getPadEscape
     * @see DecimalFormat#setFormatWidth
     * @see DecimalFormat#setPadPosition
     * @see DecimalFormat#setPadCharacter
     * @stable ICU 2.0
     */
    public void setPadEscape(char c) {
        padEscape = c;
    }

    /**
     * {@icu} Indicates the currency match pattern used in {@link #getPatternForCurrencySpacing}.
     * @stable ICU 4.2
     */
    public static final int CURRENCY_SPC_CURRENCY_MATCH =
            CurrencySpacingInfo.SpacingPattern.CURRENCY_MATCH.ordinal();

    /**
     * {@icu} Indicates the surrounding match pattern used in {@link
     * #getPatternForCurrencySpacing}.
     * @stable ICU 4.2
     */
    public static final int CURRENCY_SPC_SURROUNDING_MATCH =
            CurrencySpacingInfo.SpacingPattern.SURROUNDING_MATCH.ordinal();

    /**
     * {@icu} Indicates the insertion value used in {@link #getPatternForCurrencySpacing}.
     * @stable ICU 4.4
     */
    public static final int CURRENCY_SPC_INSERT =
            CurrencySpacingInfo.SpacingPattern.INSERT_BETWEEN.ordinal();

    private String[] currencySpcBeforeSym;
    private String[] currencySpcAfterSym;

    /**
     * {@icu} Returns the desired currency spacing value. Original values come from ICU's
     * CLDR data based on the locale provided during construction, and can be null.  These
     * values govern what and when text is inserted between a currency code/name/symbol
     * and the currency amount when formatting money.
     *
     * <p>For more information, see <a href="http://www.unicode.org/reports/tr35/#Currencies"
     * >UTS#35 section 5.10.2</a>.
     *
     * <p><strong>Note:</strong> ICU4J does not currently use this information.
     *
     * @param itemType one of CURRENCY_SPC_CURRENCY_MATCH, CURRENCY_SPC_SURROUNDING_MATCH
     * or CURRENCY_SPC_INSERT
     * @param beforeCurrency true to get the <code>beforeCurrency</code> values, false
     * to get the <code>afterCurrency</code> values.
     * @return the value, or null.
     * @see #setPatternForCurrencySpacing(int, boolean, String)
     * @stable ICU 4.2
     */
    public String getPatternForCurrencySpacing(int itemType, boolean beforeCurrency)  {
        if (itemType < CURRENCY_SPC_CURRENCY_MATCH ||
            itemType > CURRENCY_SPC_INSERT ) {
            throw new IllegalArgumentException("unknown currency spacing: " + itemType);
        }
        if (beforeCurrency) {
            return currencySpcBeforeSym[itemType];
        }
        return currencySpcAfterSym[itemType];
    }

    /**
     * {@icu} Sets the indicated currency spacing pattern or value. See {@link
     * #getPatternForCurrencySpacing} for more information.
     *
     * <p>Values for currency match and surrounding match must be {@link
     * com.ibm.icu.text.UnicodeSet} patterns. Values for insert can be any string.
     *
     * <p><strong>Note:</strong> ICU4J does not currently use this information.
     *
     * @param itemType one of CURRENCY_SPC_CURRENCY_MATCH, CURRENCY_SPC_SURROUNDING_MATCH
     * or CURRENCY_SPC_INSERT
     * @param beforeCurrency true if the pattern is for before the currency symbol.
     * false if the pattern is for after it.
     * @param  pattern string to override current setting; can be null.
     * @see #getPatternForCurrencySpacing(int, boolean)
     * @stable ICU 4.2
     */
    public void setPatternForCurrencySpacing(int itemType, boolean beforeCurrency, String pattern) {
        if (itemType < CURRENCY_SPC_CURRENCY_MATCH ||
            itemType > CURRENCY_SPC_INSERT ) {
            throw new IllegalArgumentException("unknown currency spacing: " + itemType);
        }
        if (beforeCurrency) {
            currencySpcBeforeSym[itemType] = pattern;
        } else {
            currencySpcAfterSym[itemType] = pattern;
        }
    }

    /**
     * Returns the locale for which this object was constructed.
     * @return the locale for which this object was constructed
     * @stable ICU 2.0
     */
    public Locale getLocale() {
        return requestedLocale;
    }

    /**
     * Returns the locale for which this object was constructed.
     * @return the locale for which this object was constructed
     * @stable ICU 3.2
     */
    public ULocale getULocale() {
        return ulocale;
    }

    /**
     * {@inheritDoc}
     * @stable ICU 2.0
     */
    @Override
    public Object clone() {
        try {
            return super.clone();
            // other fields are bit-copied
        } catch (CloneNotSupportedException e) {
            ///CLOVER:OFF
            throw new ICUCloneNotSupportedException(e);
            ///CLOVER:ON
        }
    }

    /**
     * {@inheritDoc}
     * @stable ICU 2.0
     */
    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof DecimalFormatSymbols)) {
            return false;
        }
        if (this == obj) {
            return true;
        }
        DecimalFormatSymbols other = (DecimalFormatSymbols) obj;
        for (int i = 0; i <= CURRENCY_SPC_INSERT; i++) {
            if (!currencySpcBeforeSym[i].equals(other.currencySpcBeforeSym[i])) {
                return false;
            }
            if (!currencySpcAfterSym[i].equals(other.currencySpcAfterSym[i])) {
                return false;
            }
        }

        if ( other.digits == null ) {
            for (int i = 0 ; i < 10 ; i++) {
                if (digits[i] != other.zeroDigit + i) {
                    return false;
                }
            }
        } else if (!Arrays.equals(digits,other.digits)) {
                    return false;
        }

        return (
        groupingSeparator == other.groupingSeparator &&
        decimalSeparator == other.decimalSeparator &&
        percent == other.percent &&
        perMill == other.perMill &&
        digit == other.digit &&
        minusSign == other.minusSign &&
        minusString.equals(other.minusString) &&
        patternSeparator == other.patternSeparator &&
        infinity.equals(other.infinity) &&
        NaN.equals(other.NaN) &&
        currencySymbol.equals(other.currencySymbol) &&
        intlCurrencySymbol.equals(other.intlCurrencySymbol) &&
        padEscape == other.padEscape &&
        plusSign == other.plusSign &&
        plusString.equals(other.plusString) &&
        exponentSeparator.equals(other.exponentSeparator) &&
        monetarySeparator == other.monetarySeparator &&
        monetaryGroupingSeparator == other.monetaryGroupingSeparator &&
        exponentMultiplicationSign.equals(other.exponentMultiplicationSign));
    }

    /**
     * {@inheritDoc}
     * @stable ICU 2.0
     */
    @Override
    public int hashCode() {
            int result = digits[0];
            result = result * 37 + groupingSeparator;
            result = result * 37 + decimalSeparator;
            return result;
    }

    /**
     * List of field names to be loaded from the data files.
     * The indices of each name into the array correspond to the position of that item in the
     * numberElements array.
     */
    private static final String[] SYMBOL_KEYS = {
            "decimal",
            "group",
            "list",
            "percentSign",
            "minusSign",
            "plusSign",
            "exponential",
            "perMille",
            "infinity",
            "nan",
            "currencyDecimal",
            "currencyGroup",
            "superscriptingExponent"
    };

    /*
     * Default digits
     */
    private static final String[] DEF_DIGIT_STRINGS_ARRAY =
        {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};

    private static final char[] DEF_DIGIT_CHARS_ARRAY =
        {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};

    /*
     *  Default symbol characters, used for fallbacks.
     */
    private static final char DEF_DECIMAL_SEPARATOR = '.';
    private static final char DEF_GROUPING_SEPARATOR = ',';
    private static final char DEF_PERCENT = '%';
    private static final char DEF_MINUS_SIGN = '-';
    private static final char DEF_PLUS_SIGN = '+';
    private static final char DEF_PERMILL = '\u2030';

    /**
     * List of default values for the symbols.
     */
    private static final String[] SYMBOL_DEFAULTS = new String[] {
            String.valueOf(DEF_DECIMAL_SEPARATOR),  // decimal
            String.valueOf(DEF_GROUPING_SEPARATOR), // group
            ";", // list
            String.valueOf(DEF_PERCENT),    // percentSign
            String.valueOf(DEF_MINUS_SIGN), // minusSign
            String.valueOf(DEF_PLUS_SIGN),  // plusSign
            "E", // exponential
            String.valueOf(DEF_PERMILL),    // perMille
            "\u221e", // infinity
            "NaN", // NaN
            null, // currency decimal
            null, // currency group
            "\u00D7" // superscripting exponent
        };

    /**
     * Constants for path names in the data bundles.
     */
    private static final String LATIN_NUMBERING_SYSTEM = "latn";
    private static final String NUMBER_ELEMENTS = "NumberElements";
    private static final String SYMBOLS = "symbols";

    /**
     * Sink for enumerating all of the decimal format symbols (more specifically, anything
     * under the "NumberElements.symbols" tree).
     *
     * More specific bundles (en_GB) are enumerated before their parents (en_001, en, root):
     * Only store a value if it is still missing, that is, it has not been overridden.
     */
    private static final class DecFmtDataSink extends UResource.Sink {

        private String[] numberElements; // Array where to store the characters (set in constructor)

        public DecFmtDataSink(String[] numberElements) {
            this.numberElements = numberElements;
        }

        @Override
        public void put(UResource.Key key, UResource.Value value, boolean noFallback) {
            UResource.Table symbolsTable = value.getTable();
            for (int j = 0; symbolsTable.getKeyAndValue(j, key, value); ++j) {
                for (int i = 0; i < SYMBOL_KEYS.length; i++) {
                    if (key.contentEquals(SYMBOL_KEYS[i])) {
                        if (numberElements[i] == null) {
                            numberElements[i] = value.toString();
                        }
                        break;
                    }
                }
            }
        }
    }

    /**
     * Initializes the symbols from the locale data.
     */
    private void initialize( ULocale locale ) {
        this.requestedLocale = locale.toLocale();
        this.ulocale = locale;
        CacheData data = cachedLocaleData.getInstance(locale, null /* unused */);
        setLocale(data.validLocale, data.validLocale);
        setDigitStrings(data.digits);
        String[] numberElements = data.numberElements;

        // Copy data from the numberElements map into instance fields
        setDecimalSeparatorString(numberElements[0]);
        setGroupingSeparatorString(numberElements[1]);

        // See CLDR #9781
        // assert numberElements[2].length() == 1;
        patternSeparator = numberElements[2].charAt(0);

        setPercentString(numberElements[3]);
        setMinusSignString(numberElements[4]);
        setPlusSignString(numberElements[5]);
        setExponentSeparator(numberElements[6]);
        setPerMillString(numberElements[7]);
        setInfinity(numberElements[8]);
        setNaN(numberElements[9]);
        setMonetaryDecimalSeparatorString(numberElements[10]);
        setMonetaryGroupingSeparatorString(numberElements[11]);
        setExponentMultiplicationSign(numberElements[12]);

        digit = DecimalFormat.PATTERN_DIGIT;  // Localized pattern character no longer in CLDR
        padEscape = DecimalFormat.PATTERN_PAD_ESCAPE;
        sigDigit  = DecimalFormat.PATTERN_SIGNIFICANT_DIGIT;


        CurrencyDisplayInfo info = CurrencyData.provider.getInstance(locale, true);

        // Obtain currency data from the currency API.  This is strictly
        // for backward compatibility; we don't use DecimalFormatSymbols
        // for currency data anymore.
        currency = Currency.getInstance(locale);
        if (currency != null) {
            intlCurrencySymbol = currency.getCurrencyCode();
            currencySymbol = currency.getName(locale, Currency.SYMBOL_NAME, null);
            CurrencyFormatInfo fmtInfo = info.getFormatInfo(intlCurrencySymbol);
            if (fmtInfo != null) {
                currencyPattern = fmtInfo.currencyPattern;
                setMonetaryDecimalSeparatorString(fmtInfo.monetarySeparator);
                setMonetaryGroupingSeparatorString(fmtInfo.monetaryGroupingSeparator);
            }
        } else {
            intlCurrencySymbol = "XXX";
            currencySymbol = "\u00A4"; // 'OX' currency symbol
        }


        // Get currency spacing data.
        initSpacingInfo(info.getSpacingInfo());
    }

    private static CacheData loadData(ULocale locale) {
        String nsName;
        // Attempt to set the decimal digits based on the numbering system for the requested locale.
        NumberingSystem ns = NumberingSystem.getInstance(locale);
        String[] digits = new String[10];
        if (ns != null && ns.getRadix() == 10 && !ns.isAlgorithmic() &&
                NumberingSystem.isValidDigitString(ns.getDescription())) {
            String digitString = ns.getDescription();

            for (int i = 0, offset = 0; i < 10; i++) {
                int cp = digitString.codePointAt(offset);
                int nextOffset = offset + Character.charCount(cp);
                digits[i] = digitString.substring(offset, nextOffset);
                offset = nextOffset;
            }
            nsName = ns.getName();
        } else {
            // Default numbering system
            digits = DEF_DIGIT_STRINGS_ARRAY;
            nsName = "latn";
        }

        // Open the resource bundle and get the locale IDs.
        // TODO: Is there a better way to get the locale than making an ICUResourceBundle instance?
        ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.
                getBundleInstance(ICUData.ICU_BASE_NAME, locale);
        // TODO: Determine actual and valid locale correctly.
        ULocale validLocale = rb.getULocale();

        String[] numberElements = new String[SYMBOL_KEYS.length];

        // Load using a data sink
        DecFmtDataSink sink = new DecFmtDataSink(numberElements);
        try {
            rb.getAllItemsWithFallback(NUMBER_ELEMENTS + "/" + nsName + "/" + SYMBOLS, sink);
        } catch (MissingResourceException e) {
            // The symbols don't exist for the given nsName and resource bundle.
            // Silently ignore and fall back to Latin.
        }

        // Load the Latin fallback if necessary
        boolean hasNull = false;
        for (String entry : numberElements) {
            if (entry == null) {
                hasNull = true;
                break;
            }
        }
        if (hasNull && !nsName.equals(LATIN_NUMBERING_SYSTEM)) {
            rb.getAllItemsWithFallback(NUMBER_ELEMENTS + "/" + LATIN_NUMBERING_SYSTEM + "/" + SYMBOLS, sink);
        }

        // Fill in any remaining missing values
        for (int i = 0; i < SYMBOL_KEYS.length; i++) {
            if (numberElements[i] == null) {
                numberElements[i] = SYMBOL_DEFAULTS[i];
            }
        }

        // If monetary decimal or grouping were not explicitly set, then set them to be the same as
        // their non-monetary counterparts.
        if (numberElements[10] == null) {
            numberElements[10] = numberElements[0];
        }
        if (numberElements[11] == null) {
            numberElements[11] = numberElements[1];
        }

        return new CacheData(validLocale, digits, numberElements);
    }

    private void initSpacingInfo(CurrencySpacingInfo spcInfo) {
        currencySpcBeforeSym = spcInfo.getBeforeSymbols();
        currencySpcAfterSym = spcInfo.getAfterSymbols();
    }

    /**
     * Reads the default serializable fields, then if <code>serialVersionOnStream</code>
     * is less than 1, initialize <code>monetarySeparator</code> to be
     * the same as <code>decimalSeparator</code> and <code>exponential</code>
     * to be 'E'.
     * Finally, sets 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 {

        // TODO: it looks to me {dlf} that the serialization code was never updated
        // to handle the actual/valid ulocale fields.

        stream.defaultReadObject();
        ///CLOVER:OFF
        // we don't have data for these old serialized forms any more
        if (serialVersionOnStream < 1) {
            // Didn't have monetarySeparator or exponential field;
            // use defaults.
            monetarySeparator = decimalSeparator;
            exponential = 'E';
        }
        if (serialVersionOnStream < 2) {
            padEscape = DecimalFormat.PATTERN_PAD_ESCAPE;
            plusSign = DecimalFormat.PATTERN_PLUS_SIGN;
            exponentSeparator = String.valueOf(exponential);
            // Although we read the exponential field on stream to create the
            // exponentSeparator, we don't do the reverse, since scientific
            // notation isn't supported by the old classes, even though the
            // symbol is there.
        }
        ///CLOVER:ON
        if (serialVersionOnStream < 3) {
            // Resurrected objects from old streams will have no
            // locale.  There is no 100% fix for this.  A
            // 90% fix is to construct a mapping of data back to
            // locale, perhaps a hash of all our members.  This is
            // expensive and doesn't seem worth it.
            requestedLocale = Locale.getDefault();
        }
        if (serialVersionOnStream < 4) {
            // use same default behavior as for versions with no Locale
            ulocale = ULocale.forLocale(requestedLocale);
        }
        if (serialVersionOnStream < 5) {
            // use the same one for groupingSeparator
            monetaryGroupingSeparator = groupingSeparator;
        }
        if (serialVersionOnStream < 6) {
            // Set null to CurrencySpacing related fields.
            if (currencySpcBeforeSym == null) {
                currencySpcBeforeSym = new String[CURRENCY_SPC_INSERT+1];
            }
            if (currencySpcAfterSym == null) {
                currencySpcAfterSym = new String[CURRENCY_SPC_INSERT+1];
            }
            initSpacingInfo(CurrencyData.CurrencySpacingInfo.DEFAULT);
        }
        if (serialVersionOnStream < 7) {
            // Set minusString,plusString from minusSign,plusSign
            if (minusString == null) {
                minusString = String.valueOf(minusSign);
            }
            if (plusString == null) {
                plusString = String.valueOf(plusSign);
            }
        }
        if (serialVersionOnStream < 8) {
            if (exponentMultiplicationSign == null) {
                exponentMultiplicationSign = "\u00D7";
            }
        }
        if (serialVersionOnStream < 9) {
            // String version of digits
            if (digitStrings == null) {
                digitStrings = new String[10];
                if (digits != null && digits.length == 10) {
                    zeroDigit = digits[0];
                    for (int i = 0; i < 10; i++) {
                        digitStrings[i] = String.valueOf(digits[i]);
                    }
                } else {
                    char digit = zeroDigit;
                    if (digits == null) {
                        digits = new char[10];
                    }
                    for (int i = 0; i < 10; i++) {
                        digits[i] = digit;
                        digitStrings[i] = String.valueOf(digit);
                        digit++;
                    }
                }
            }

            // String version of symbols
            if (decimalSeparatorString == null) {
                decimalSeparatorString = String.valueOf(decimalSeparator);
            }
            if (groupingSeparatorString == null) {
                groupingSeparatorString = String.valueOf(groupingSeparator);
            }
            if (percentString == null) {
                percentString = String.valueOf(percentString);
            }
            if (perMillString == null) {
                perMillString = String.valueOf(perMill);
            }
            if (monetarySeparatorString == null) {
                monetarySeparatorString = String.valueOf(monetarySeparator);
            }
            if (monetaryGroupingSeparatorString == null) {
                monetaryGroupingSeparatorString = String.valueOf(monetaryGroupingSeparator);
            }
        }

        serialVersionOnStream = currentSerialVersion;

    // recreate
    currency = Currency.getInstance(intlCurrencySymbol);
    }

    /**
     * Character used for zero.  This remains only for backward compatibility
     * purposes.  The digits array below is now used to actively store the digits.
     *
     * @serial
     * @see #getZeroDigit
     */
    private  char    zeroDigit;

    /**
     * Array of characters used for the digits 0-9 in order.
     */
    private  char    digits[];

    /**
     * Array of Strings used for the digits 0-9 in order.
     * @serial
     */
    private String digitStrings[];

    /**
     * Character used for thousands separator.
     *
     * @serial
     * @see #getGroupingSeparator
     */
    private  char    groupingSeparator;

    /**
     * String used for thousands separator.
     * @serial
     */
    private String groupingSeparatorString;

    /**
     * Character used for decimal sign.
     *
     * @serial
     * @see #getDecimalSeparator
     */
    private  char    decimalSeparator;

    /**
     * String used for decimal sign.
     * @serial
     */
    private String decimalSeparatorString;

    /**
     * Character used for mille percent sign.
     *
     * @serial
     * @see #getPerMill
     */
    private  char    perMill;

    /**
     * String used for mille percent sign.
     * @serial
     */
    private String perMillString;

    /**
     * Character used for percent sign.
     * @serial
     * @see #getPercent
     */
    private  char    percent;

    /**
     * String used for percent sign.
     * @serial
     */
    private String percentString;

    /**
     * Character used for a digit in a pattern.
     *
     * @serial
     * @see #getDigit
     */
    private  char    digit;

    /**
     * Character used for a significant digit in a pattern.
     *
     * @serial
     * @see #getSignificantDigit
     */
    private  char    sigDigit;

    /**
     * Character used to separate positive and negative subpatterns
     * in a pattern.
     *
     * @serial
     * @see #getPatternSeparator
     */
    private  char    patternSeparator;

    /**
     * Character used to represent infinity.
     * @serial
     * @see #getInfinity
     */
    private  String  infinity;

    /**
     * Character used to represent NaN.
     * @serial
     * @see #getNaN
     */
    private  String  NaN;

    /**
     * Character used to represent minus sign.
     * @serial
     * @see #getMinusSign
     */
    private  char    minusSign;

    /**
     * String versions of minus sign.
     * @serial
     * @since ICU 52
     */
    private String minusString;

    /**
     * The character used to indicate a plus sign.
     * @serial
     * @since AlphaWorks
     */
    private char plusSign;

    /**
     * String versions of plus sign.
     * @serial
     * @since ICU 52
     */
    private String plusString;

    /**
     * String denoting the local currency, e.g. "$".
     * @serial
     * @see #getCurrencySymbol
     */
    private  String  currencySymbol;

    /**
     * International string denoting the local currency, e.g. "USD".
     * @serial
     * @see #getInternationalCurrencySymbol
     */
    private  String  intlCurrencySymbol;

    /**
     * The decimal separator character used when formatting currency values.
     * @serial
     * @see #getMonetaryDecimalSeparator
     */
    private  char    monetarySeparator; // Field new in JDK 1.1.6

    /**
     * The decimal separator string used when formatting currency values.
     * @serial
     */
    private String monetarySeparatorString;

    /**
     * The grouping separator character used when formatting currency values.
     * @serial
     * @see #getMonetaryGroupingSeparator
     */
    private  char    monetaryGroupingSeparator; // Field new in JDK 1.1.6

    /**
     * The grouping separator string used when formatting currency values.
     * @serial
     */
    private String monetaryGroupingSeparatorString;

    /**
     * The character used to distinguish the exponent in a number formatted
     * in exponential notation, e.g. 'E' for a number such as "1.23E45".
     * <p>
     * Note that this field has been superseded by <code>exponentSeparator</code>.
     * It is retained for backward compatibility.
     *
     * @serial
     */
    private  char    exponential;       // Field new in JDK 1.1.6

    /**
     * The string used to separate the mantissa from the exponent.
     * Examples: "x10^" for 1.23x10^4, "E" for 1.23E4.
     * <p>
     * Note that this supersedes the <code>exponential</code> field.
     *
     * @serial
     * @since AlphaWorks
     */
    private String exponentSeparator;

    /**
     * The character used to indicate a padding character in a format,
     * e.g., '*' in a pattern such as "$*_#,##0.00".
     * @serial
     * @since AlphaWorks
     */
    private char padEscape;

    /**
     * The locale for which this object was constructed.  Set to the
     * default locale for objects resurrected from old streams.
     * @since ICU 2.2
     */
    private Locale requestedLocale;

    /**
     * The requested ULocale.  We keep the old locale for serialization compatibility.
     * @since ICU 3.2
     */
    private ULocale ulocale;

    /**
     * Exponent multiplication sign. e.g "x"
     * @serial
     * @since ICU 54
     */
    private String exponentMultiplicationSign = null;

    // Proclaim JDK 1.1 FCS compatibility
    private static final long serialVersionUID = 5772796243397350300L;

    // The internal serial version which says which version was written
    // - 0 (default) for version up to JDK 1.1.5
    // - 1 for version from JDK 1.1.6, which includes two new fields:
    //     monetarySeparator and exponential.
    // - 2 for version from AlphaWorks, which includes 3 new fields:
    //     padEscape, exponentSeparator, and plusSign.
    // - 3 for ICU 2.2, which includes the locale field
    // - 4 for ICU 3.2, which includes the ULocale field
    // - 5 for ICU 3.6, which includes the monetaryGroupingSeparator field
    // - 6 for ICU 4.2, which includes the currencySpc* fields
    // - 7 for ICU 52, which includes the minusString and plusString fields
    // - 8 for ICU 54, which includes exponentMultiplicationSign field.
    // - 9 for ICU 58, which includes a series of String symbol fields.
    private static final int currentSerialVersion = 8;

    /**
     * Describes the version of <code>DecimalFormatSymbols</code> present on the stream.
     * Possible values are:
     * <ul>
     * <li><b>0</b> (or uninitialized): versions prior to JDK 1.1.6.
     *
     * <li><b>1</b>: Versions written by JDK 1.1.6 or later, which includes
     *      two new fields: <code>monetarySeparator</code> and <code>exponential</code>.
     * <li><b>2</b>: Version for AlphaWorks.  Adds padEscape, exponentSeparator,
     *      and plusSign.
     * <li><b>3</b>: Version for ICU 2.2, which adds locale.
     * <li><b>4</b>: Version for ICU 3.2, which adds ulocale.
     * <li><b>5</b>: Version for ICU 3.6, which adds monetaryGroupingSeparator.
     * <li><b>6</b>: Version for ICU 4.2, which adds currencySpcBeforeSym and
     *      currencySpcAfterSym.
     * <li><b>7</b>: Version for ICU 52, which adds minusString and plusString.
     * </ul>
     * When streaming out a <code>DecimalFormatSymbols</code>, the most recent format
     * (corresponding to the highest allowable <code>serialVersionOnStream</code>)
     * is always written.
     *
     * @serial
     */
    private int serialVersionOnStream = currentSerialVersion;

    /**
     * cache to hold the NumberElements of a Locale.
     */
    private static final CacheBase<ULocale, CacheData, Void> cachedLocaleData =
        new SoftCache<ULocale, CacheData, Void>() {
            @Override
            protected CacheData createInstance(ULocale locale, Void unused) {
                return DecimalFormatSymbols.loadData(locale);
            }
        };

    /**
     *
     */
    private String  currencyPattern = null;

    // -------- BEGIN ULocale boilerplate --------

    /**
     * {@icu} Returns the locale that was used to create this object, or null.
     * This may may differ from the locale requested at the time of
     * this object's creation.  For example, if an object is created
     * for locale <tt>en_US_CALIFORNIA</tt>, the actual data may be
     * drawn from <tt>en</tt> (the <i>actual</i> locale), and
     * <tt>en_US</tt> may be the most specific locale that exists (the
     * <i>valid</i> locale).
     *
     * <p>Note: The <i>actual</i> locale is returned correctly, but the <i>valid</i>
     * locale is not, in most cases.
     * @param type type of information requested, either {@link
     * com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link
     * com.ibm.icu.util.ULocale#ACTUAL_LOCALE}.
     * @return the information specified by <i>type</i>, or null if
     * this object was not constructed from locale data.
     * @see com.ibm.icu.util.ULocale
     * @see com.ibm.icu.util.ULocale#VALID_LOCALE
     * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE
     * @draft ICU 2.8 (retain)
     * @provisional This API might change or be removed in a future release.
     */
    public final ULocale getLocale(ULocale.Type type) {
        return type == ULocale.ACTUAL_LOCALE ?
            this.actualLocale : this.validLocale;
    }

    /**
     * {@icu} Sets information about the locales that were used to create this
     * object.  If the object was not constructed from locale data,
     * both arguments should be set to null.  Otherwise, neither
     * should be null.  The actual locale must be at the same level or
     * less specific than the valid locale.  This method is intended
     * for use by factories or other entities that create objects of
     * this class.
     * @param valid the most specific locale containing any resource
     * data, or null
     * @param actual the locale containing data used to construct this
     * object, or null
     * @see com.ibm.icu.util.ULocale
     * @see com.ibm.icu.util.ULocale#VALID_LOCALE
     * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE
     */
    final void setLocale(ULocale valid, ULocale actual) {
        // Change the following to an assertion later
        if ((valid == null) != (actual == null)) {
            ///CLOVER:OFF
            throw new IllegalArgumentException();
            ///CLOVER:ON
        }
        // Another check we could do is that the actual locale is at
        // the same level or less specific than the valid locale.
        this.validLocale = valid;
        this.actualLocale = actual;
    }

    /**
     * The most specific locale containing any resource data, or null.
     * @see com.ibm.icu.util.ULocale
     */
    private ULocale validLocale;

    /**
     * The locale containing data used to construct this object, or
     * null.
     * @see com.ibm.icu.util.ULocale
     */
    private ULocale actualLocale;

    // not serialized, reconstructed from intlCurrencyCode
    private transient Currency currency;

    // -------- END ULocale boilerplate --------

    private static class CacheData {
        final ULocale validLocale;
        final String[] digits;
        final String[] numberElements;

        public CacheData(ULocale loc, String[] digits, String[] numberElements) {
            validLocale = loc;
            this.digits = digits;
            this.numberElements = numberElements;
        }
    }
}
