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

import java.text.ParsePosition;

//===================================================================
// NFSubstitution (abstract base class)
//===================================================================

/**
 * An abstract class defining protocol for substitutions.  A substitution
 * is a section of a rule that inserts text into the rule's rule text
 * based on some part of the number being formatted.
 * @author Richard Gillam
 */
abstract class NFSubstitution {
    //-----------------------------------------------------------------------
    // data members
    //-----------------------------------------------------------------------

    /**
     * The substitution's position in the rule text of the rule that owns it
     */
    final int pos;

    /**
     * The rule set this substitution uses to format its result, or null.
     * (Either this or numberFormat has to be non-null.)
     */
    final NFRuleSet ruleSet;

    /**
     * The DecimalFormat this substitution uses to format its result,
     * or null.  (Either this or ruleSet has to be non-null.)
     */
    final DecimalFormat numberFormat;

    //-----------------------------------------------------------------------
    // construction
    //-----------------------------------------------------------------------

    /**
     * Parses the description, creates the right kind of substitution,
     * and initializes it based on the description.
     * @param pos The substitution's position in the rule text of the
     * rule that owns it.
     * @param rule The rule containing this substitution
     * @param rulePredecessor The rule preceding the one that contains
     * this substitution in the rule set's rule list (this is used
     * only for >>> substitutions).
     * @param ruleSet The rule set containing the rule containing this
     * substitution
     * @param formatter The RuleBasedNumberFormat that ultimately owns
     * this substitution
     * @param description The description to parse to build the substitution
     * (this is just the substring of the rule's description containing
     * the substitution token itself)
     * @return A new substitution constructed according to the description
     */
    public static NFSubstitution makeSubstitution(int pos,
                                                  NFRule rule,
                                                  NFRule rulePredecessor,
                                                  NFRuleSet ruleSet,
                                                  RuleBasedNumberFormat formatter,
                                                  String description) {
        // if the description is empty, return a NullSubstitution
        if (description.length() == 0) {
            return null;
        }

        switch (description.charAt(0)) {
        case '<':
            if (rule.getBaseValue() == NFRule.NEGATIVE_NUMBER_RULE) {
                // throw an exception if the rule is a negative number rule
                ///CLOVER:OFF
                // If you look at the call hierarchy of this method, the rule would
                // never be directly modified by the user and therefore makes the
                // following pointless unless the user changes the ruleset.
                throw new IllegalArgumentException("<< not allowed in negative-number rule");
                ///CLOVER:ON
            }
            else if (rule.getBaseValue() == NFRule.IMPROPER_FRACTION_RULE
                     || rule.getBaseValue() == NFRule.PROPER_FRACTION_RULE
                     || rule.getBaseValue() == NFRule.MASTER_RULE)
            {
                // if the rule is a fraction rule, return an IntegralPartSubstitution
                return new IntegralPartSubstitution(pos, ruleSet, description);
            }
            else if (ruleSet.isFractionSet()) {
                // if the rule set containing the rule is a fraction
                // rule set, return a NumeratorSubstitution
                return new NumeratorSubstitution(pos, rule.getBaseValue(),
                                                 formatter.getDefaultRuleSet(), description);
            }
            else {
                // otherwise, return a MultiplierSubstitution
                return new MultiplierSubstitution(pos, rule.getDivisor(), ruleSet,
                                                  description);
            }

        case '>':
            if (rule.getBaseValue() == NFRule.NEGATIVE_NUMBER_RULE) {
                // if the rule is a negative-number rule, return
                // an AbsoluteValueSubstitution
                return new AbsoluteValueSubstitution(pos, ruleSet, description);
            }
            else if (rule.getBaseValue() == NFRule.IMPROPER_FRACTION_RULE
                     || rule.getBaseValue() == NFRule.PROPER_FRACTION_RULE
                     || rule.getBaseValue() == NFRule.MASTER_RULE)
            {
                // if the rule is a fraction rule, return a
                // FractionalPartSubstitution
                return new FractionalPartSubstitution(pos, ruleSet, description);
            }
            else if (ruleSet.isFractionSet()) {
                // if the rule set owning the rule is a fraction rule set,
                // throw an exception
                ///CLOVER:OFF
                // If you look at the call hierarchy of this method, the rule would
                // never be directly modified by the user and therefore makes the
                // following pointless unless the user changes the ruleset.
                throw new IllegalArgumentException(">> not allowed in fraction rule set");
                ///CLOVER:ON
            }
            else {
                // otherwise, return a ModulusSubstitution
                return new ModulusSubstitution(pos, rule.getDivisor(), rulePredecessor,
                                               ruleSet, description);
            }
        case '=':
            return new SameValueSubstitution(pos, ruleSet, description);
        default:
            // and if it's anything else, throw an exception
            ///CLOVER:OFF
            // If you look at the call hierarchy of this method, the rule would
            // never be directly modified by the user and therefore makes the
            // following pointless unless the user changes the ruleset.
            throw new IllegalArgumentException("Illegal substitution character");
            ///CLOVER:ON
        }
    }

    /**
     * Base constructor for substitutions.  This constructor sets up the
     * fields which are common to all substitutions.
     * @param pos The substitution's position in the owning rule's rule
     * text
     * @param ruleSet The rule set that owns this substitution
     * @param description The substitution descriptor (i.e., the text
     * inside the token characters)
     */
    NFSubstitution(int pos,
                   NFRuleSet ruleSet,
                   String description) {
        // initialize the substitution's position in its parent rule
        this.pos = pos;
        int descriptionLen = description.length();

        // the description should begin and end with the same character.
        // If it doesn't that's a syntax error.  Otherwise,
        // makeSubstitution() was the only thing that needed to know
        // about these characters, so strip them off
        if (descriptionLen >= 2 && description.charAt(0) == description.charAt(descriptionLen - 1)) {
            description = description.substring(1, descriptionLen - 1);
        }
        else if (descriptionLen != 0) {
            throw new IllegalArgumentException("Illegal substitution syntax");
        }

        // if the description was just two paired token characters
        // (i.e., "<<" or ">>"), it uses the rule set it belongs to to
        // format its result
        if (description.length() == 0) {
            this.ruleSet = ruleSet;
            this.numberFormat = null;
        }
        else if (description.charAt(0) == '%') {
            // if the description contains a rule set name, that's the rule
            // set we use to format the result: get a reference to the
            // names rule set
            this.ruleSet = ruleSet.owner.findRuleSet(description);
            this.numberFormat = null;
        }
        else if (description.charAt(0) == '#' || description.charAt(0) == '0') {
            // if the description begins with 0 or #, treat it as a
            // DecimalFormat pattern, and initialize a DecimalFormat with
            // that pattern (then set it to use the DecimalFormatSymbols
            // belonging to our formatter)
            this.ruleSet = null;
            this.numberFormat = (DecimalFormat) ruleSet.owner.getDecimalFormat().clone();
            this.numberFormat.applyPattern(description);
        }
        else if (description.charAt(0) == '>') {
            // if the description is ">>>", this substitution bypasses the
            // usual rule-search process and always uses the rule that precedes
            // it in its own rule set's rule list (this is used for place-value
            // notations: formats where you want to see a particular part of
            // a number even when it's 0)
            this.ruleSet = ruleSet; // was null, thai rules added to control space
            this.numberFormat = null;
        }
        else {
            // and of the description is none of these things, it's a syntax error
            throw new IllegalArgumentException("Illegal substitution syntax");
        }
    }

    /**
     * Set's the substitution's divisor.  Used by NFRule.setBaseValue().
     * A no-op for all substitutions except multiplier and modulus
     * substitutions.
     * @param radix The radix of the divisor
     * @param exponent The exponent of the divisor
     */
    public void setDivisor(int radix, int exponent) {
        // a no-op for all substitutions except multiplier and modulus substitutions
    }

    //-----------------------------------------------------------------------
    // boilerplate
    //-----------------------------------------------------------------------

    /**
     * Compares two substitutions for equality
     * @param that The substitution to compare this one to
     * @return true if the two substitutions are functionally equivalent
     */
    public boolean equals(Object that) {
        // compare class and all of the fields all substitutions have
        // in common
        if (that == null) {
            return false;
        }
        if (this == that) {
            return true;
        }
        if (this.getClass() == that.getClass()) {
            NFSubstitution that2 = (NFSubstitution)that;

            return pos == that2.pos
                && (ruleSet != null || that2.ruleSet == null) // can't compare tree structure, no .equals or recurse
                && (numberFormat == null ? (that2.numberFormat == null) : numberFormat.equals(that2.numberFormat));
        }
        return false;
    }
    
    public int hashCode() {
        assert false : "hashCode not designed";
        return 42;
    }

    /**
     * Returns a textual description of the substitution
     * @return A textual description of the substitution.  This might
     * not be identical to the description it was created from, but
     * it'll produce the same result.
     */
    public String toString() {
        // use tokenChar() to get the character at the beginning and
        // end of the substitution token.  In between them will go
        // either the name of the rule set it uses, or the pattern of
        // the DecimalFormat it uses
        if (ruleSet != null) {
            return tokenChar() + ruleSet.getName() + tokenChar();
        } else {
            return tokenChar() + numberFormat.toPattern() + tokenChar();
        }
    }

    //-----------------------------------------------------------------------
    // formatting
    //-----------------------------------------------------------------------

    /**
     * Performs a mathematical operation on the number, formats it using
     * either ruleSet or decimalFormat, and inserts the result into
     * toInsertInto.
     * @param number The number being formatted.
     * @param toInsertInto The string we insert the result into
     * @param position The position in toInsertInto where the owning rule's
     * rule text begins (this value is added to this substitution's
     * position to determine exactly where to insert the new text)
     */
    public void doSubstitution(long number, StringBuffer toInsertInto, int position, int recursionCount) {
        if (ruleSet != null) {
            // perform a transformation on the number that is dependent
            // on the type of substitution this is, then just call its
            // rule set's format() method to format the result
            long numberToFormat = transformNumber(number);

            ruleSet.format(numberToFormat, toInsertInto, position + pos, recursionCount);
        } else {
            // or perform the transformation on the number (preserving
            // the result's fractional part if the formatter it set
            // to show it), then use that formatter's format() method
            // to format the result
            double numberToFormat = transformNumber((double)number);
            if (numberFormat.getMaximumFractionDigits() == 0) {
                numberToFormat = Math.floor(numberToFormat);
            }

            toInsertInto.insert(position + pos, numberFormat.format(numberToFormat));
        }
    }

    /**
     * Performs a mathematical operation on the number, formats it using
     * either ruleSet or decimalFormat, and inserts the result into
     * toInsertInto.
     * @param number The number being formatted.
     * @param toInsertInto The string we insert the result into
     * @param position The position in toInsertInto where the owning rule's
     * rule text begins (this value is added to this substitution's
     * position to determine exactly where to insert the new text)
     */
    public void doSubstitution(double number, StringBuffer toInsertInto, int position, int recursionCount) {
        // perform a transformation on the number being formatted that
        // is dependent on the type of substitution this is
        double numberToFormat = transformNumber(number);

        if (Double.isInfinite(numberToFormat)) {
            // This is probably a minus rule. Combine it with an infinite rule.
            NFRule infiniteRule = ruleSet.findRule(Double.POSITIVE_INFINITY);
            infiniteRule.doFormat(numberToFormat, toInsertInto, position + pos, recursionCount);
            return;
        }

        // if the result is an integer, from here on out we work in integer
        // space (saving time and memory and preserving accuracy)
        if (numberToFormat == Math.floor(numberToFormat) && ruleSet != null) {
            ruleSet.format((long)numberToFormat, toInsertInto, position + pos, recursionCount);

            // if the result isn't an integer, then call either our rule set's
            // format() method or our DecimalFormat's format() method to
            // format the result
        } else {
            if (ruleSet != null) {
                ruleSet.format(numberToFormat, toInsertInto, position + pos, recursionCount);
            } else {
                toInsertInto.insert(position + this.pos, numberFormat.format(numberToFormat));
            }
        }
    }

    /**
     * Subclasses override this function to perform some kind of
     * mathematical operation on the number.  The result of this operation
     * is formatted using the rule set or DecimalFormat that this
     * substitution refers to, and the result is inserted into the result
     * string.
     * @param number The number being formatted
     * @return The result of performing the opreration on the number
     */
    public abstract long transformNumber(long number);

    /**
     * Subclasses override this function to perform some kind of
     * mathematical operation on the number.  The result of this operation
     * is formatted using the rule set or DecimalFormat that this
     * substitution refers to, and the result is inserted into the result
     * string.
     * @param number The number being formatted
     * @return The result of performing the opreration on the number
     */
    public abstract double transformNumber(double number);

    //-----------------------------------------------------------------------
    // parsing
    //-----------------------------------------------------------------------

    /**
     * Parses a string using the rule set or DecimalFormat belonging
     * to this substitution.  If there's a match, a mathematical
     * operation (the inverse of the one used in formatting) is
     * performed on the result of the parse and the value passed in
     * and returned as the result.  The parse position is updated to
     * point to the first unmatched character in the string.
     * @param text The string to parse
     * @param parsePosition On entry, ignored, but assumed to be 0.
     * On exit, this is updated to point to the first unmatched
     * character (or 0 if the substitution didn't match)
     * @param baseValue A partial parse result that should be
     * combined with the result of this parse
     * @param upperBound When searching the rule set for a rule
     * matching the string passed in, only rules with base values
     * lower than this are considered
     * @param lenientParse If true and matching against rules fails,
     * the substitution will also try matching the text against
     * numerals using a default-constructed NumberFormat.  If false,
     * no extra work is done.  (This value is false whenever the
     * formatter isn't in lenient-parse mode, but is also false
     * under some conditions even when the formatter _is_ in
     * lenient-parse mode.)
     * @return If there's a match, this is the result of composing
     * baseValue with whatever was returned from matching the
     * characters.  This will be either a Long or a Double.  If there's
     * no match this is new Long(0) (not null), and parsePosition
     * is left unchanged.
     */
    public Number doParse(String text, ParsePosition parsePosition, double baseValue,
                          double upperBound, boolean lenientParse) {
        Number tempResult;

        // figure out the highest base value a rule can have and match
        // the text being parsed (this varies according to the type of
        // substitutions: multiplier, modulus, and numerator substitutions
        // restrict the search to rules with base values lower than their
        // own; same-value substitutions leave the upper bound wherever
        // it was, and the others allow any rule to match
        upperBound = calcUpperBound(upperBound);

        // use our rule set to parse the text.  If that fails and
        // lenient parsing is enabled (this is always false if the
        // formatter's lenient-parsing mode is off, but it may also
        // be false even when the formatter's lenient-parse mode is
        // on), then also try parsing the text using a default-
        // constructed NumberFormat
        if (ruleSet != null) {
            tempResult = ruleSet.parse(text, parsePosition, upperBound);
            if (lenientParse && !ruleSet.isFractionSet() && parsePosition.getIndex() == 0) {
                tempResult = ruleSet.owner.getDecimalFormat().parse(text, parsePosition);
            }

            // ...or use our DecimalFormat to parse the text
        } else {
            tempResult = numberFormat.parse(text, parsePosition);
        }

        // if the parse was successful, we've already advanced the caller's
        // parse position (this is the one function that doesn't have one
        // of its own).  Derive a parse result and return it as a Long,
        // if possible, or a Double
        if (parsePosition.getIndex() != 0) {
            double result = tempResult.doubleValue();

            // composeRuleValue() produces a full parse result from
            // the partial parse result passed to this function from
            // the caller (this is either the owning rule's base value
            // or the partial result obtained from composing the
            // owning rule's base value with its other substitution's
            // parse result) and the partial parse result obtained by
            // matching the substitution (which will be the same value
            // the caller would get by parsing just this part of the
            // text with RuleBasedNumberFormat.parse() ).  How the two
            // values are used to derive the full parse result depends
            // on the types of substitutions: For a regular rule, the
            // ultimate result is its multiplier substitution's result
            // times the rule's divisor (or the rule's base value) plus
            // the modulus substitution's result (which will actually
            // supersede part of the rule's base value).  For a negative-
            // number rule, the result is the negative of its substitution's
            // result.  For a fraction rule, it's the sum of its two
            // substitution results.  For a rule in a fraction rule set,
            // it's the numerator substitution's result divided by
            // the rule's base value.  Results from same-value substitutions
            // propagate back upward, and null substitutions don't affect
            // the result.
            result = composeRuleValue(result, baseValue);
            if (result == (long)result) {
                return Long.valueOf((long)result);
            } else {
                return new Double(result);
            }

            // if the parse was UNsuccessful, return 0
        } else {
            return tempResult;
        }
    }

    /**
     * Derives a new value from the two values passed in.  The two values
     * are typically either the base values of two rules (the one containing
     * the substitution and the one matching the substitution) or partial
     * parse results derived in some other way.  The operation is generally
     * the inverse of the operation performed by transformNumber().
     * @param newRuleValue The value produced by matching this substitution
     * @param oldRuleValue The value that was passed to the substitution
     * by the rule that owns it
     * @return A third value derived from the other two, representing a
     * partial parse result
     */
    public abstract double composeRuleValue(double newRuleValue, double oldRuleValue);

    /**
     * Calculates an upper bound when searching for a rule that matches
     * this substitution.  Rules with base values greater than or equal
     * to upperBound are not considered.
     * @param oldUpperBound The current upper-bound setting.  The new
     * upper bound can't be any higher.
     */
    public abstract double calcUpperBound(double oldUpperBound);

    //-----------------------------------------------------------------------
    // simple accessors
    //-----------------------------------------------------------------------

    /**
     * Returns the substitution's position in the rule that owns it.
     * @return The substitution's position in the rule that owns it.
     */
    public final int getPos() {
        return pos;
    }

    /**
     * Returns the character used in the textual representation of
     * substitutions of this type.  Used by toString().
     * @return This substitution's token character.
     */
    abstract char tokenChar();

    /**
     * Returns true if this is a modulus substitution.  (We didn't do this
     * with instanceof partially because it causes source files to
     * proliferate and partially because we have to port this to C++.)
     * @return true if this object is an instance of ModulusSubstitution
     */
    public boolean isModulusSubstitution() {
        return false;
    }


    public void setDecimalFormatSymbols(DecimalFormatSymbols newSymbols) {
        if (numberFormat != null) {
            numberFormat.setDecimalFormatSymbols(newSymbols);
        }
    }
}

//===================================================================
// SameValueSubstitution
//===================================================================

/**
 * A substitution that passes the value passed to it through unchanged.
 * Represented by == in rule descriptions.
 */
class SameValueSubstitution extends NFSubstitution {
    //-----------------------------------------------------------------------
    // construction
    //-----------------------------------------------------------------------

    /**
     * Constructs a SameValueSubstution.  This function just uses the
     * superclass constructor, but it performs a check that this
     * substitution doesn't call the rule set that owns it, since that
     * would lead to infinite recursion.
     */
    SameValueSubstitution(int pos,
                          NFRuleSet ruleSet,
                          String description) {
        super(pos, ruleSet, description);
        if (description.equals("==")) {
            throw new IllegalArgumentException("== is not a legal token");
        }
    }

    //-----------------------------------------------------------------------
    // formatting
    //-----------------------------------------------------------------------

    /**
     * Returns "number" unchanged.
     * @return "number"
     */
    public long transformNumber(long number) {
        return number;
    }

    /**
     * Returns "number" unchanged.
     * @return "number"
     */
    public double transformNumber(double number) {
        return number;
    }

    //-----------------------------------------------------------------------
    // parsing
    //-----------------------------------------------------------------------

    /**
     * Returns newRuleValue and ignores oldRuleValue. (The value we got
     * matching the substitution supersedes the value of the rule
     * that owns the substitution.)
     * @param newRuleValue The value resulting from matching the substitution
     * @param oldRuleValue The value of the rule containing the
     * substitution.
     * @return newRuleValue
     */
    public double composeRuleValue(double newRuleValue, double oldRuleValue) {
        return newRuleValue;
    }

    /**
     * SameValueSubstitution doesn't change the upper bound.
     * @param oldUpperBound The current upper bound.
     * @return oldUpperBound
     */
    public double calcUpperBound(double oldUpperBound) {
        return oldUpperBound;
    }

    //-----------------------------------------------------------------------
    // simple accessor
    //-----------------------------------------------------------------------

    /**
     * The token character for a SameValueSubstitution is =.
     * @return '='
     */
    char tokenChar() {
        return '=';
    }
}

//===================================================================
// MultiplierSubstitution
//===================================================================

/**
 * A substitution that divides the number being formatted by the rule's
 * divisor and formats the quotient.  Represented by &lt;&lt; in normal
 * rules.
 */
class MultiplierSubstitution extends NFSubstitution {
    //-----------------------------------------------------------------------
    // data members
    //-----------------------------------------------------------------------

    /**
     * The divisor of the rule that owns this substitution.
     */
    double divisor;

    //-----------------------------------------------------------------------
    // construction
    //-----------------------------------------------------------------------

    /**
     * Constructs a MultiplierSubstitution.  This uses the superclass
     * constructor to initialize most members, but this substitution
     * also maintains its own copy of its rule's divisor.
     * @param pos The substitution's position in its rule's rule text
     * @param divisor The owning rule's divisor
     * @param ruleSet The ruleSet this substitution uses to format its result
     * @param description The description describing this substitution
     */
    MultiplierSubstitution(int pos,
                           double divisor,
                           NFRuleSet ruleSet,
                           String description) {
        super(pos, ruleSet, description);

        // the owning rule's divisor affects the behavior of this
        // substitution.  Rather than keeping a back-pointer to the
        // rule, we keep a copy of the divisor
        this.divisor = divisor;

        if (divisor == 0) { // this will cause recursion
            throw new IllegalStateException("Substitution with divisor 0 " + description.substring(0, pos) +
                         " | " + description.substring(pos));
        }
    }

    /**
     * Sets the substitution's divisor based on the values passed in.
     * @param radix The radix of the divisor.
     * @param exponent The exponent of the divisor.
     */
    public void setDivisor(int radix, int exponent) {
        divisor = Math.pow(radix, exponent);

        if (divisor == 0) {
            throw new IllegalStateException("Substitution with divisor 0");
        }
    }

    //-----------------------------------------------------------------------
    // boilerplate
    //-----------------------------------------------------------------------

    /**
     * Augments the superclass's equals() function by comparing divisors.
     * @param that The other substitution
     * @return true if the two substitutions are functionally equal
     */
    public boolean equals(Object that) {
        return super.equals(that) && divisor == ((MultiplierSubstitution) that).divisor;
    }
    
    //-----------------------------------------------------------------------
    // formatting
    //-----------------------------------------------------------------------

    /**
     * Divides the number by the rule's divisor and returns the quotient.
     * @param number The number being formatted.
     * @return "number" divided by the rule's divisor
     */
    public long transformNumber(long number) {
        return (long)Math.floor(number / divisor);
    }

    /**
     * Divides the number by the rule's divisor and returns the quotient.
     * This is an integral quotient if we're filling in the substitution
     * using another rule set, but it's the full quotient (integral and
     * fractional parts) if we're filling in the substitution using
     * a DecimalFormat.  (This allows things such as "1.2 million".)
     * @param number The number being formatted
     * @return "number" divided by the rule's divisor
     */
    public double transformNumber(double number) {
        if (ruleSet == null) {
            return number / divisor;
        } else {
            return Math.floor(number / divisor);
        }
    }

    //-----------------------------------------------------------------------
    // parsing
    //-----------------------------------------------------------------------

    /**
     * Returns newRuleValue times the divisor.  Ignores oldRuleValue.
     * (The result of matching a << substitution supersedes the base
     * value of the rule that contains it.)
     * @param newRuleValue The result of matching the substitution
     * @param oldRuleValue The base value of the rule containing the
     * substitution
     * @return newRuleValue * divisor
     */
    public double composeRuleValue(double newRuleValue, double oldRuleValue) {
        return newRuleValue * divisor;
    }

    /**
     * Sets the upper bound down to the rule's divisor.
     * @param oldUpperBound Ignored.
     * @return The rule's divisor.
     */
    public double calcUpperBound(double oldUpperBound) {
        return divisor;
    }

    //-----------------------------------------------------------------------
    // simple accessor
    //-----------------------------------------------------------------------

    /**
     * The token character for a multiplier substitution is &lt;.
     * @return '&lt;'
     */
    char tokenChar() {
        return '<';
    }
}

//===================================================================
// ModulusSubstitution
//===================================================================

/**
 * A substitution that divides the number being formatted by the its rule's
 * divisor and formats the remainder.  Represented by "&gt;&gt;" in a
 * regular rule.
 */
class ModulusSubstitution extends NFSubstitution {
    //-----------------------------------------------------------------------
    // data members
    //-----------------------------------------------------------------------

    /**
     * The divisor of the rule owning this substitution
     */
    double divisor;

    /**
     * If this is a &gt;&gt;&gt; substitution, the rule to use to format
     * the substitution value.  Otherwise, null.
     */
    private final NFRule ruleToUse;

    //-----------------------------------------------------------------------
    // construction
    //-----------------------------------------------------------------------

    /**
     * Constructs a ModulusSubstitution.  In addition to the inherited
     * members, a ModulusSubstitution keeps track of the divisor of the
     * rule that owns it, and may also keep a reference to the rule
     * that precedes the rule containing this substitution in the rule
     * set's rule list.
     * @param pos The substitution's position in its rule's rule text
     * @param divisor The divisor of the rule that owns this substitution
     * @param rulePredecessor The rule that precedes this substitution's
     * rule in its rule set's rule list
     * @param description The description for this substitution
     */
    ModulusSubstitution(int pos,
                        double divisor,
                        NFRule rulePredecessor,
                        NFRuleSet ruleSet,
                        String description)
    {
        super(pos, ruleSet, description);

        // the owning rule's divisor controls the behavior of this
        // substitution: rather than keeping a backpointer to the rule,
        // we keep a copy of the divisor
        this.divisor = divisor;

        if (divisor == 0) { // this will cause recursion
            throw new IllegalStateException("Substitution with bad divisor (" + divisor + ") "+ description.substring(0, pos) +
                    " | " + description.substring(pos));
        }

        // the >>> token doesn't alter how this substitution calculates the
        // values it uses for formatting and parsing, but it changes
        // what's done with that value after it's obtained: >>> short-
        // circuits the rule-search process and goes straight to the
        // specified rule to format the substitution value
        if (description.equals(">>>")) {
            ruleToUse = rulePredecessor;
        } else {
            ruleToUse = null;
        }
    }

    /**
     * Makes the substitution's divisor conform to that of the rule
     * that owns it.  Used when the divisor is determined after creation.
     * @param radix The radix of the divisor.
     * @param exponent The exponent of the divisor.
     */
    public void setDivisor(int radix, int exponent) {
        divisor = Math.pow(radix, exponent);

        if (divisor == 0) { // this will cause recursion
            throw new IllegalStateException("Substitution with bad divisor");
        }
    }

    //-----------------------------------------------------------------------
    // boilerplate
    //-----------------------------------------------------------------------

    /**
     * Augments the inherited equals() function by comparing divisors and
     * ruleToUse.
     * @param that The other substitution
     * @return true if the two substitutions are functionally equivalent
     */
    public boolean equals(Object that) {
        if (super.equals(that)) {
            ModulusSubstitution that2 = (ModulusSubstitution)that;

            return divisor == that2.divisor;
        } else {
            return false;
        }
    }
    
    //-----------------------------------------------------------------------
    // formatting
    //-----------------------------------------------------------------------

    /**
     * If this is a &gt;&gt;&gt; substitution, use ruleToUse to fill in
     * the substitution.  Otherwise, just use the superclass function.
     * @param number The number being formatted
     * @param toInsertInto The string to insert the result of this substitution
     * into
     * @param position The position of the rule text in toInsertInto
     */
    public void doSubstitution(long number, StringBuffer toInsertInto, int position, int recursionCount) {
        // if this isn't a >>> substitution, just use the inherited version
        // of this function (which uses either a rule set or a DecimalFormat
        // to format its substitution value)
        if (ruleToUse == null) {
            super.doSubstitution(number, toInsertInto, position, recursionCount);

        } else {
            // a >>> substitution goes straight to a particular rule to
            // format the substitution value
            long numberToFormat = transformNumber(number);
            ruleToUse.doFormat(numberToFormat, toInsertInto, position + pos, recursionCount);
        }
    }

    /**
     * If this is a &gt;&gt;&gt; substitution, use ruleToUse to fill in
     * the substitution.  Otherwise, just use the superclass function.
     * @param number The number being formatted
     * @param toInsertInto The string to insert the result of this substitution
     * into
     * @param position The position of the rule text in toInsertInto
     */
    public void doSubstitution(double number, StringBuffer toInsertInto, int position, int recursionCount) {
        // if this isn't a >>> substitution, just use the inherited version
        // of this function (which uses either a rule set or a DecimalFormat
        // to format its substitution value)
        if (ruleToUse == null) {
            super.doSubstitution(number, toInsertInto, position, recursionCount);

        } else {
            // a >>> substitution goes straight to a particular rule to
            // format the substitution value
            double numberToFormat = transformNumber(number);

            ruleToUse.doFormat(numberToFormat, toInsertInto, position + pos, recursionCount);
        }
    }

    /**
     * Divides the number being formatted by the rule's divisor and
     * returns the remainder.
     * @param number The number being formatted
     * @return "number" mod divisor
     */
    public long transformNumber(long number) {
        return (long)Math.floor(number % divisor);
    }

    /**
     * Divides the number being formatted by the rule's divisor and
     * returns the remainder.
     * @param number The number being formatted
     * @return "number" mod divisor
     */
    public double transformNumber(double number) {
        return Math.floor(number % divisor);
    }

    //-----------------------------------------------------------------------
    // parsing
    //-----------------------------------------------------------------------

    /**
     * If this is a &gt;&gt;&gt; substitution, match only against ruleToUse.
     * Otherwise, use the superclass function.
     * @param text The string to parse
     * @param parsePosition Ignored on entry, updated on exit to point to
     * the first unmatched character.
     * @param baseValue The partial parse result prior to calling this
     * routine.
     */
    public Number doParse(String text, ParsePosition parsePosition, double baseValue,
                        double upperBound, boolean lenientParse) {
        // if this isn't a >>> substitution, we can just use the
        // inherited parse() routine to do the parsing
        if (ruleToUse == null) {
            return super.doParse(text, parsePosition, baseValue, upperBound, lenientParse);

        } else {
            // but if it IS a >>> substitution, we have to do it here: we
            // use the specific rule's doParse() method, and then we have to
            // do some of the other work of NFRuleSet.parse()
            Number tempResult = ruleToUse.doParse(text, parsePosition, false, upperBound);

            if (parsePosition.getIndex() != 0) {
                double result = tempResult.doubleValue();

                result = composeRuleValue(result, baseValue);
                if (result == (long)result) {
                    return Long.valueOf((long)result);
                } else {
                    return new Double(result);
                }
            } else {
                return tempResult;
            }
        }
    }

    /**
     * Returns the highest multiple of the rule's divisor that its less
     * than or equal to oldRuleValue, plus newRuleValue.  (The result
     * is the sum of the result of parsing the substitution plus the
     * base value of the rule containing the substitution, but if the
     * owning rule's base value isn't an even multiple of its divisor,
     * we have to round it down to a multiple of the divisor, or we
     * get unwanted digits in the result.)
     * @param newRuleValue The result of parsing the substitution
     * @param oldRuleValue The base value of the rule containing the
     * substitution
     */
    public double composeRuleValue(double newRuleValue, double oldRuleValue) {
        return (oldRuleValue - (oldRuleValue % divisor)) + newRuleValue;
    }

    /**
     * Sets the upper bound down to the owning rule's divisor
     * @param oldUpperBound Ignored
     * @return The owning rule's divisor
     */
    public double calcUpperBound(double oldUpperBound) {
        return divisor;
    }

    //-----------------------------------------------------------------------
    // simple accessors
    //-----------------------------------------------------------------------

    /**
     * Returns true.  This _is_ a ModulusSubstitution.
     * @return true
     */
    public boolean isModulusSubstitution() {
        return true;
    }

    /**
     * The token character of a ModulusSubstitution is &gt;.
     * @return '&gt;'
     */
    char tokenChar() {
        return '>';
    }
}

//===================================================================
// IntegralPartSubstitution
//===================================================================

/**
 * A substitution that formats the number's integral part.  This is
 * represented by &lt;&lt; in a fraction rule.
 */
class IntegralPartSubstitution extends NFSubstitution {
    //-----------------------------------------------------------------------
    // construction
    //-----------------------------------------------------------------------

    /**
     * Constructs an IntegralPartSubstitution.  This just calls
     * the superclass constructor.
     */
    IntegralPartSubstitution(int pos,
                             NFRuleSet ruleSet,
                             String description) {
        super(pos, ruleSet, description);
    }

    //-----------------------------------------------------------------------
    // formatting
    //-----------------------------------------------------------------------

    /**
     * Returns the number's integral part. (For a long, that's just the
     * number unchanged.)
     * @param number The number being formatted
     * @return "number" unchanged
     */
    public long transformNumber(long number) {
        return number;
    }

    /**
     * Returns the number's integral part.
     * @param number The integral part of the number being formatted
     * @return floor(number)
     */
    public double transformNumber(double number) {
        return Math.floor(number);
    }

    //-----------------------------------------------------------------------
    // parsing
    //-----------------------------------------------------------------------

    /**
     * Returns the sum of the result of parsing the substitution and the
     * owning rule's base value.  (The owning rule, at best, has an
     * integral-part substitution and a fractional-part substitution,
     * so we can safely just add them.)
     * @param newRuleValue The result of matching the substitution
     * @param oldRuleValue The partial result of the parse prior to
     * calling this function
     * @return oldRuleValue + newRuleValue
     */
    public double composeRuleValue(double newRuleValue, double oldRuleValue) {
        return newRuleValue + oldRuleValue;
    }

    /**
     * An IntegralPartSubstitution sets the upper bound back up so all
     * potentially matching rules are considered.
     * @param oldUpperBound Ignored
     * @return Double.MAX_VALUE
     */
    public double calcUpperBound(double oldUpperBound) {
        return Double.MAX_VALUE;
    }

    //-----------------------------------------------------------------------
    // simple accessor
    //-----------------------------------------------------------------------

    /**
     * An IntegralPartSubstitution's token character is &lt;
     * @return '&lt;'
     */
    char tokenChar() {
        return '<';
    }
}

//===================================================================
// FractionalPartSubstitution
//===================================================================

/**
 * A substitution that formats the fractional part of a number.  This is
 * represented by &gt;&gt; in a fraction rule.
 */
class FractionalPartSubstitution extends NFSubstitution {
    //-----------------------------------------------------------------------
    // data members
    //-----------------------------------------------------------------------

    /**
     * true if this substitution should have the default "by digits"
     * behavior, false otherwise
     */
    private final boolean byDigits;

    /**
     * true if we automatically insert spaces to separate names of digits
     * set to false by '>>>' in fraction rules, used by Thai.
     */
    private final boolean useSpaces;

    //-----------------------------------------------------------------------
    // construction
    //-----------------------------------------------------------------------

    /**
     * Constructs a FractionalPartSubstitution.  This object keeps a flag
     * telling whether it should format by digits or not.  In addition,
     * it marks the rule set it calls (if any) as a fraction rule set.
     */
    FractionalPartSubstitution(int pos,
                               NFRuleSet ruleSet,
                               String description) {
        super(pos, ruleSet, description);
        if (description.equals(">>") || description.equals(">>>") || ruleSet == this.ruleSet) {
            byDigits = true;
            useSpaces = !description.equals(">>>");
        } else {
            byDigits = false;
            useSpaces = true;
            this.ruleSet.makeIntoFractionRuleSet();
        }
    }

    //-----------------------------------------------------------------------
    // formatting
    //-----------------------------------------------------------------------

    /**
     * If in "by digits" mode, fills in the substitution one decimal digit
     * at a time using the rule set containing this substitution.
     * Otherwise, uses the superclass function.
     * @param number The number being formatted
     * @param toInsertInto The string to insert the result of formatting
     * the substitution into
     * @param position The position of the owning rule's rule text in
     * toInsertInto
     */
    public void doSubstitution(double number, StringBuffer toInsertInto, int position, int recursionCount) {
        if (!byDigits) {
            // if we're not in "byDigits" mode, just use the inherited
            // doSubstitution() routine
            super.doSubstitution(number, toInsertInto, position, recursionCount);
        }
        else {
            // if we're in "byDigits" mode, transform the value into an integer
            // by moving the decimal point eight places to the right and
            // pulling digits off the right one at a time, formatting each digit
            // as an integer using this substitution's owning rule set
            // (this is slower, but more accurate, than doing it from the
            // other end)

            // just print to string and then use that
            DigitList dl = new DigitList();
            dl.set(number, 20, true);

            boolean pad = false;
            while (dl.count > Math.max(0, dl.decimalAt)) {
                if (pad && useSpaces) {
                    toInsertInto.insert(position + pos, ' ');
                } else {
                    pad = true;
                }
                ruleSet.format(dl.digits[--dl.count] - '0', toInsertInto, position + pos, recursionCount);
            }
            while (dl.decimalAt < 0) {
                if (pad && useSpaces) {
                    toInsertInto.insert(position + pos, ' ');
                } else {
                    pad = true;
                }
                ruleSet.format(0, toInsertInto, position + pos, recursionCount);
                ++dl.decimalAt;
            }
        }
    }

    /**
     * Returns the fractional part of the number, which will always be
     * zero if it's a long.
     * @param number The number being formatted
     * @return 0
     */
    public long transformNumber(long number) {
        return 0;
    }

    /**
     * Returns the fractional part of the number.
     * @param number The number being formatted.
     * @return number - floor(number)
     */
    public double transformNumber(double number) {
        return number - Math.floor(number);
    }

    //-----------------------------------------------------------------------
    // parsing
    //-----------------------------------------------------------------------

    /**
     * If in "by digits" mode, parses the string as if it were a string
     * of individual digits; otherwise, uses the superclass function.
     * @param text The string to parse
     * @param parsePosition Ignored on entry, but updated on exit to point
     * to the first unmatched character
     * @param baseValue The partial parse result prior to entering this
     * function
     * @param upperBound Only consider rules with base values lower than
     * this when filling in the substitution
     * @param lenientParse If true, try matching the text as numerals if
     * matching as words doesn't work
     * @return If the match was successful, the current partial parse
     * result; otherwise new Long(0).  The result is either a Long or
     * a Double.
     */
    public Number doParse(String text, ParsePosition parsePosition, double baseValue,
                        double upperBound, boolean lenientParse) {
        // if we're not in byDigits mode, we can just use the inherited
        // doParse()
        if (!byDigits) {
            return super.doParse(text, parsePosition, baseValue, 0, lenientParse);
        }
        else {
            // if we ARE in byDigits mode, parse the text one digit at a time
            // using this substitution's owning rule set (we do this by setting
            // upperBound to 10 when calling doParse() ) until we reach
            // nonmatching text
            String workText = text;
            ParsePosition workPos = new ParsePosition(1);
            double result;
            int digit;

            DigitList dl = new DigitList();
            while (workText.length() > 0 && workPos.getIndex() != 0) {
                workPos.setIndex(0);
                digit = ruleSet.parse(workText, workPos, 10).intValue();
                if (lenientParse && workPos.getIndex() == 0) {
                    Number n = ruleSet.owner.getDecimalFormat().parse(workText, workPos);
                    if (n != null) {
                        digit = n.intValue();
                    }
                }

                if (workPos.getIndex() != 0) {
                    dl.append('0'+digit);

                    parsePosition.setIndex(parsePosition.getIndex() + workPos.getIndex());
                    workText = workText.substring(workPos.getIndex());
                    while (workText.length() > 0 && workText.charAt(0) == ' ') {
                        workText = workText.substring(1);
                        parsePosition.setIndex(parsePosition.getIndex() + 1);
                    }
                }
            }
            result = dl.count == 0 ? 0 : dl.getDouble();

            result = composeRuleValue(result, baseValue);
            return new Double(result);
        }
    }

    /**
     * Returns the sum of the two partial parse results.
     * @param newRuleValue The result of parsing the substitution
     * @param oldRuleValue The partial parse result prior to calling
     * this function
     * @return newRuleValue + oldRuleValue
     */
    public double composeRuleValue(double newRuleValue, double oldRuleValue) {
        return newRuleValue + oldRuleValue;
    }

    /**
     * Not used.
     */
    public double calcUpperBound(double oldUpperBound) {
        return 0;   // this value is ignored
    }

    //-----------------------------------------------------------------------
    // simple accessor
    //-----------------------------------------------------------------------

    /**
     * The token character for a FractionalPartSubstitution is &gt;.
     * @return '&gt;'
     */
    char tokenChar() {
        return '>';
    }
}

//===================================================================
// AbsoluteValueSubstitution
//===================================================================

 /**
  * A substitution that formats the absolute value of the number.
  * This substitution is represented by &gt;&gt; in a negative-number rule.
  */
class AbsoluteValueSubstitution extends NFSubstitution {
    //-----------------------------------------------------------------------
    // construction
    //-----------------------------------------------------------------------

    /**
     * Constructs an AbsoluteValueSubstitution.  This just uses the
     * superclass constructor.
     */
    AbsoluteValueSubstitution(int pos,
                              NFRuleSet ruleSet,
                              String description) {
        super(pos, ruleSet, description);
    }

    //-----------------------------------------------------------------------
    // formatting
    //-----------------------------------------------------------------------

    /**
     * Returns the absolute value of the number.
     * @param number The number being formatted.
     * @return abs(number)
     */
    public long transformNumber(long number) {
        return Math.abs(number);
    }

    /**
     * Returns the absolute value of the number.
     * @param number The number being formatted.
     * @return abs(number)
     */
    public double transformNumber(double number) {
        return Math.abs(number);
    }

    //-----------------------------------------------------------------------
    // parsing
    //-----------------------------------------------------------------------

    /**
     * Returns the additive inverse of the result of parsing the
     * substitution (this supersedes the earlier partial result)
     * @param newRuleValue The result of parsing the substitution
     * @param oldRuleValue The partial parse result prior to calling
     * this function
     * @return -newRuleValue
     */
    public double composeRuleValue(double newRuleValue, double oldRuleValue) {
        return -newRuleValue;
    }

    /**
     * Sets the upper bound beck up to consider all rules
     * @param oldUpperBound Ignored.
     * @return Double.MAX_VALUE
     */
    public double calcUpperBound(double oldUpperBound) {
        return Double.MAX_VALUE;
    }

    //-----------------------------------------------------------------------
    // simple accessor
    //-----------------------------------------------------------------------

    /**
     * The token character for an AbsoluteValueSubstitution is &gt;
     * @return '&gt;'
     */
    char tokenChar() {
        return '>';
    }
}

//===================================================================
// NumeratorSubstitution
//===================================================================

/**
 * A substitution that multiplies the number being formatted (which is
 * between 0 and 1) by the base value of the rule that owns it and
 * formats the result.  It is represented by &lt;&lt; in the rules
 * in a fraction rule set.
 */
class NumeratorSubstitution extends NFSubstitution {
    //-----------------------------------------------------------------------
    // data members
    //-----------------------------------------------------------------------

    /**
     * The denominator of the fraction we're finding the numerator for.
     * (The base value of the rule that owns this substitution.)
     */
    private final double denominator;

    /**
     * True if we format leading zeros (this is a hack for Hebrew spellout)
     */
    private final boolean withZeros;

    //-----------------------------------------------------------------------
    // construction
    //-----------------------------------------------------------------------

    /**
     * Constructs a NumeratorSubstitution.  In addition to the inherited
     * fields, a NumeratorSubstitution keeps track of a denominator, which
     * is merely the base value of the rule that owns it.
     */
    NumeratorSubstitution(int pos,
                          double denominator,
                          NFRuleSet ruleSet,
                          String description) {
        super(pos, ruleSet, fixdesc(description));

        // this substitution's behavior depends on the rule's base value
        // Rather than keeping a backpointer to the rule, we copy its
        // base value here
        this.denominator = denominator;
        
        this.withZeros = description.endsWith("<<");
    }

    static String fixdesc(String description) {
        return description.endsWith("<<") 
            ? description.substring(0,description.length()-1) 
            : description;
    }

    //-----------------------------------------------------------------------
    // boilerplate
    //-----------------------------------------------------------------------

    /**
     * Tests two NumeratorSubstitutions for equality
     * @param that The other NumeratorSubstitution
     * @return true if the two objects are functionally equivalent
     */
    public boolean equals(Object that) {
        if (super.equals(that)) {
            NumeratorSubstitution that2 = (NumeratorSubstitution)that;
            return denominator == that2.denominator && withZeros == that2.withZeros;
        } else {
            return false;
        }
    }
    
    //-----------------------------------------------------------------------
    // formatting
    //-----------------------------------------------------------------------

    /**
     * Performs a mathematical operation on the number, formats it using
     * either ruleSet or decimalFormat, and inserts the result into
     * toInsertInto.
     * @param number The number being formatted.
     * @param toInsertInto The string we insert the result into
     * @param position The position in toInsertInto where the owning rule's
     * rule text begins (this value is added to this substitution's
     * position to determine exactly where to insert the new text)
     */
    public void doSubstitution(double number, StringBuffer toInsertInto, int position, int recursionCount) {
        // perform a transformation on the number being formatted that
        // is dependent on the type of substitution this is
        //String s = toInsertInto.toString();
        double numberToFormat = transformNumber(number);

        if (withZeros && ruleSet != null) {
            // if there are leading zeros in the decimal expansion then emit them
            long nf = (long)numberToFormat;
            int len = toInsertInto.length();
            while ((nf *= 10) < denominator) {
                toInsertInto.insert(position + pos, ' ');
                ruleSet.format(0, toInsertInto, position + pos, recursionCount);
            }
            position += toInsertInto.length() - len;
        }

        // if the result is an integer, from here on out we work in integer
        // space (saving time and memory and preserving accuracy)
        if (numberToFormat == Math.floor(numberToFormat) && ruleSet != null) {
            ruleSet.format((long)numberToFormat, toInsertInto, position + pos, recursionCount);

            // if the result isn't an integer, then call either our rule set's
            // format() method or our DecimalFormat's format() method to
            // format the result
        } else {
            if (ruleSet != null) {
                ruleSet.format(numberToFormat, toInsertInto, position + pos, recursionCount);
            } else {
                toInsertInto.insert(position + pos, numberFormat.format(numberToFormat));
            }
        }
    }

    /**
     * Returns the number being formatted times the denominator.
     * @param number The number being formatted
     * @return number * denominator
     */
    public long transformNumber(long number) {
        return Math.round(number * denominator);
    }

    /**
     * Returns the number being formatted times the denominator.
     * @param number The number being formatted
     * @return number * denominator
     */
    public double transformNumber(double number) {
        return Math.round(number * denominator);
    }

    //-----------------------------------------------------------------------
    // parsing
    //-----------------------------------------------------------------------

    /**
     * Dispatches to the inherited version of this function, but makes
     * sure that lenientParse is off.
     */
    public Number doParse(String text, ParsePosition parsePosition, double baseValue,
                        double upperBound, boolean lenientParse) {
        // we don't have to do anything special to do the parsing here,
        // but we have to turn lenient parsing off-- if we leave it on,
        // it SERIOUSLY messes up the algorithm

        // if withZeros is true, we need to count the zeros
        // and use that to adjust the parse result
        int zeroCount = 0;
        if (withZeros) {
            String workText = text;
            ParsePosition workPos = new ParsePosition(1);
            //int digit;

            while (workText.length() > 0 && workPos.getIndex() != 0) {
                workPos.setIndex(0);
                /*digit = */ruleSet.parse(workText, workPos, 1).intValue(); // parse zero or nothing at all
                if (workPos.getIndex() == 0) {
                    // we failed, either there were no more zeros, or the number was formatted with digits
                    // either way, we're done
                    break;
                }

                ++zeroCount;
                parsePosition.setIndex(parsePosition.getIndex() + workPos.getIndex());
                workText = workText.substring(workPos.getIndex());
                while (workText.length() > 0 && workText.charAt(0) == ' ') {
                    workText = workText.substring(1);
                    parsePosition.setIndex(parsePosition.getIndex() + 1);
                }
            }

            text = text.substring(parsePosition.getIndex()); // arrgh!
            parsePosition.setIndex(0);
        }

        // we've parsed off the zeros, now let's parse the rest from our current position
        Number result =  super.doParse(text, parsePosition, withZeros ? 1 : baseValue, upperBound, false);

        if (withZeros) {
            // any base value will do in this case.  is there a way to
            // force this to not bother trying all the base values?
            
            // compute the 'effective' base and prescale the value down
            long n = result.longValue();
            long d = 1;
            while (d <= n) {
                d *= 10;
            }
            // now add the zeros
            while (zeroCount > 0) {
                d *= 10;
                --zeroCount;
            }
            // d is now our true denominator
            result = new Double(n/(double)d);
        }

        return result;
    }

    /**
     * Divides the result of parsing the substitution by the partial
     * parse result.
     * @param newRuleValue The result of parsing the substitution
     * @param oldRuleValue The owning rule's base value
     * @return newRuleValue / oldRuleValue
     */
    public double composeRuleValue(double newRuleValue, double oldRuleValue) {
        return newRuleValue / oldRuleValue;
    }

    /**
     * Sets the upper bound down to this rule's base value
     * @param oldUpperBound Ignored
     * @return The base value of the rule owning this substitution
     */
    public double calcUpperBound(double oldUpperBound) {
        return denominator;
    }

    //-----------------------------------------------------------------------
    // simple accessor
    //-----------------------------------------------------------------------

    /**
     * The token character for a NumeratorSubstitution is &lt;
     * @return '&lt;'
     */
    char tokenChar() {
        return '<';
    }
}
