/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the  "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * $Id$
 */
package org.apache.xalan.templates;

import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.NumberFormat;
import java.util.Locale;
import java.util.NoSuchElementException;

import javax.xml.transform.TransformerException;

import org.apache.xalan.res.XSLTErrorResources;
import org.apache.xalan.transformer.CountersTable;
import org.apache.xalan.transformer.DecimalToRoman;
import org.apache.xalan.transformer.TransformerImpl;
import org.apache.xml.dtm.DTM;
import org.apache.xml.utils.FastStringBuffer;
import org.apache.xml.utils.NodeVector;
import org.apache.xml.utils.PrefixResolver;
import org.apache.xml.utils.StringBufferPool;
import org.apache.xml.utils.res.XResourceBundle;
import org.apache.xml.utils.res.CharArrayWrapper;
import org.apache.xml.utils.res.IntArrayWrapper;
import org.apache.xml.utils.res.LongArrayWrapper;
import org.apache.xml.utils.res.StringArrayWrapper;
import org.apache.xpath.NodeSetDTM;
import org.apache.xpath.XPath;
import org.apache.xpath.XPathContext;
import org.apache.xpath.objects.XObject;

import org.w3c.dom.Node;

import org.xml.sax.SAXException;

// import org.apache.xalan.dtm.*;

/**
 * Implement xsl:number.
 * <pre>
 * <!ELEMENT xsl:number EMPTY>
 * <!ATTLIST xsl:number
 *    level (single|multiple|any) "single"
 *    count %pattern; #IMPLIED
 *    from %pattern; #IMPLIED
 *    value %expr; #IMPLIED
 *    format %avt; '1'
 *    lang %avt; #IMPLIED
 *    letter-value %avt; #IMPLIED
 *    grouping-separator %avt; #IMPLIED
 *    grouping-size %avt; #IMPLIED
 * >
 * </pre>
 * @see <a href="http://www.w3.org/TR/xslt#number">number in XSLT Specification</a>
 * @xsl.usage advanced
 */
public class ElemNumber extends ElemTemplateElement 
{
    static final long serialVersionUID = 8118472298274407610L;

    /**
     * Chars for converting integers into alpha counts.
     * @see TransformerImpl#int2alphaCount
     */
    private CharArrayWrapper m_alphaCountTable = null;
    
    private class MyPrefixResolver implements PrefixResolver {
        
        DTM dtm;
        int handle;
        boolean handleNullPrefix;
        
		/**
		 * Constructor for MyPrefixResolver.
		 * @param xpathExpressionContext
		 */
		public MyPrefixResolver(Node xpathExpressionContext, DTM dtm, int handle, boolean handleNullPrefix) {
            this.dtm = dtm;
            this.handle = handle;
            this.handleNullPrefix = handleNullPrefix;
		}

    	/**
		 * @see PrefixResolver#getNamespaceForPrefix(String, Node)
		 */
		public String getNamespaceForPrefix(String prefix) {
            return dtm.getNamespaceURI(handle);
		}
        
        /**
         * @see PrefixResolver#getNamespaceForPrefix(String, Node)
         * this shouldn't get called.
         */
        public String getNamespaceForPrefix(String prefix, Node context) {
            return getNamespaceForPrefix(prefix);
        }

		/**
		 * @see PrefixResolver#getBaseIdentifier()
		 */
		public String getBaseIdentifier() {
			return ElemNumber.this.getBaseIdentifier();
		}

		/**
		 * @see PrefixResolver#handlesNullPrefixes()
		 */
		public boolean handlesNullPrefixes() {
			return handleNullPrefix;
		}

}
    
  /**
   * Only nodes are counted that match this pattern.
   * @serial
   */
  private XPath m_countMatchPattern = null;

  /**
   * Set the "count" attribute.
   * The count attribute is a pattern that specifies what nodes
   * should be counted at those levels. If count attribute is not
   * specified, then it defaults to the pattern that matches any
   * node with the same node type as the current node and, if the
   * current node has an expanded-name, with the same expanded-name
   * as the current node.
   *
   * @param v Value to set for "count" attribute. 
   */
  public void setCount(XPath v)
  {
    m_countMatchPattern = v;
  }

  /**
   * Get the "count" attribute.
   * The count attribute is a pattern that specifies what nodes
   * should be counted at those levels. If count attribute is not
   * specified, then it defaults to the pattern that matches any
   * node with the same node type as the current node and, if the
   * current node has an expanded-name, with the same expanded-name
   * as the current node.
   *
   * @return Value of "count" attribute.
   */
  public XPath getCount()
  {
    return m_countMatchPattern;
  }

  /**
   * Specifies where to count from.
   * For level="single" or level="multiple":
   * Only ancestors that are searched are
   * those that are descendants of the nearest ancestor that matches
   * the from pattern.
   * For level="any:
   * Only nodes after the first node before the
   * current node that match the from pattern are considered.
   * @serial
   */
  private XPath m_fromMatchPattern = null;

  /**
   * Set the "from" attribute. Specifies where to count from.
   * For level="single" or level="multiple":
   * Only ancestors that are searched are
   * those that are descendants of the nearest ancestor that matches
   * the from pattern.
   * For level="any:
   * Only nodes after the first node before the
   * current node that match the from pattern are considered.
   *
   * @param v Value to set for "from" attribute.
   */
  public void setFrom(XPath v)
  {
    m_fromMatchPattern = v;
  }

  /**
   * Get the "from" attribute.
   * For level="single" or level="multiple":
   * Only ancestors that are searched are
   * those that are descendants of the nearest ancestor that matches
   * the from pattern.
   * For level="any:
   * Only nodes after the first node before the
   * current node that match the from pattern are considered.
   *
   * @return Value of "from" attribute.
   */
  public XPath getFrom()
  {
    return m_fromMatchPattern;
  }

  /**
   * When level="single", it goes up to the first node in the ancestor-or-self axis
   * that matches the count pattern, and constructs a list of length one containing
   * one plus the number of preceding siblings of that ancestor that match the count
   * pattern. If there is no such ancestor, it constructs an empty list. If the from
   * attribute is specified, then the only ancestors that are searched are those
   * that are descendants of the nearest ancestor that matches the from pattern.
   * Preceding siblings has the same meaning here as with the preceding-sibling axis.
   *
   * When level="multiple", it constructs a list of all ancestors of the current node
   * in document order followed by the element itself; it then selects from the list
   * those nodes that match the count pattern; it then maps each node in the list to
   * one plus the number of preceding siblings of that node that match the count pattern.
   * If the from attribute is specified, then the only ancestors that are searched are
   * those that are descendants of the nearest ancestor that matches the from pattern.
   * Preceding siblings has the same meaning here as with the preceding-sibling axis.
   *
   * When level="any", it constructs a list of length one containing the number of
   * nodes that match the count pattern and belong to the set containing the current
   * node and all nodes at any level of the document that are before the current node
   * in document order, excluding any namespace and attribute nodes (in other words
   * the union of the members of the preceding and ancestor-or-self axes). If the
   * from attribute is specified, then only nodes after the first node before the
   * current node that match the from pattern are considered.
   * @serial
   */
  private int m_level = Constants.NUMBERLEVEL_SINGLE;

  /**
   * Set the "level" attribute.
   * The level attribute specifies what levels of the source tree should
   * be considered; it has the values single, multiple or any. The default
   * is single.
   *
   * @param v Value to set for "level" attribute.
   */
  public void setLevel(int v)
  {
    m_level = v;
  }

  /**
   * Get the "level" attribute.
   * The level attribute specifies what levels of the source tree should
   * be considered; it has the values single, multiple or any. The default
   * is single.
   *
   * @return Value of "level" attribute.
   */
  public int getLevel()
  {
    return m_level;
  }

  /**
   * The value attribute contains an expression. The expression is evaluated
   * and the resulting object is converted to a number as if by a call to the
   * number function.
   * @serial
   */
  private XPath m_valueExpr = null;

  /**
   * Set the "value" attribute.
   * The value attribute contains an expression. The expression is evaluated
   * and the resulting object is converted to a number as if by a call to the
   * number function.
   *
   * @param v Value to set for "value" attribute.
   */
  public void setValue(XPath v)
  {
    m_valueExpr = v;
  }

  /**
   * Get the "value" attribute.
   * The value attribute contains an expression. The expression is evaluated
   * and the resulting object is converted to a number as if by a call to the
   * number function.
   *
   * @return Value of "value" attribute.
   */
  public XPath getValue()
  {
    return m_valueExpr;
  }

  /**
   * The "format" attribute is used to control conversion of a list of
   * numbers into a string.
   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
   * @serial
   */
  private AVT m_format_avt = null;

  /**
   * Set the "format" attribute.
   * The "format" attribute is used to control conversion of a list of
   * numbers into a string.
   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
   *
   * @param v Value to set for "format" attribute.
   */
  public void setFormat(AVT v)
  {
    m_format_avt = v;
  }

  /**
   * Get the "format" attribute.
   * The "format" attribute is used to control conversion of a list of
   * numbers into a string.
   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
   *
   * @return Value of "format" attribute.
   */
  public AVT getFormat()
  {
    return m_format_avt;
  }

  /**
   * When numbering with an alphabetic sequence, the lang attribute
   * specifies which language's alphabet is to be used.
   * @serial
   */
  private AVT m_lang_avt = null;

  /**
   * Set the "lang" attribute.
   * When numbering with an alphabetic sequence, the lang attribute
   * specifies which language's alphabet is to be used; it has the same
   * range of values as xml:lang [XML]; if no lang value is specified,
   * the language should be determined from the system environment.
   * Implementers should document for which languages they support numbering.
   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
   *
   * @param v Value to set for "lang" attribute.
   */
  public void setLang(AVT v)
  {
    m_lang_avt = v;
  }

  /**
   * Get the "lang" attribute.
   * When numbering with an alphabetic sequence, the lang attribute
   * specifies which language's alphabet is to be used; it has the same
   * range of values as xml:lang [XML]; if no lang value is specified,
   * the language should be determined from the system environment.
   * Implementers should document for which languages they support numbering.
   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
   *
   * @return Value ofr "lang" attribute.
   */
  public AVT getLang()
  {
    return m_lang_avt;
  }

  /**
   * The letter-value attribute disambiguates between numbering
   * sequences that use letters.
   * @serial
   */
  private AVT m_lettervalue_avt = null;

  /**
   * Set the "letter-value" attribute.
   * The letter-value attribute disambiguates between numbering sequences
   * that use letters.
   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
   *
   * @param v Value to set for "letter-value" attribute.
   */
  public void setLetterValue(AVT v)
  {
    m_lettervalue_avt = v;
  }

  /**
   * Get the "letter-value" attribute.
   * The letter-value attribute disambiguates between numbering sequences
   * that use letters.
   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
   *
   * @return Value to set for "letter-value" attribute.
   */
  public AVT getLetterValue()
  {
    return m_lettervalue_avt;
  }

  /**
   * The grouping-separator attribute gives the separator
   * used as a grouping (e.g. thousands) separator in decimal
   * numbering sequences.
   * @serial
   */
  private AVT m_groupingSeparator_avt = null;

  /**
   * Set the "grouping-separator" attribute.
   * The grouping-separator attribute gives the separator
   * used as a grouping (e.g. thousands) separator in decimal
   * numbering sequences.
   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
   *
   * @param v Value to set for "grouping-separator" attribute.
   */
  public void setGroupingSeparator(AVT v)
  {
    m_groupingSeparator_avt = v;
  }

  /**
   * Get the "grouping-separator" attribute.
   * The grouping-separator attribute gives the separator
   * used as a grouping (e.g. thousands) separator in decimal
   * numbering sequences.
   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
   *
   * @return Value of "grouping-separator" attribute.
   */
  public AVT getGroupingSeparator()
  {
    return m_groupingSeparator_avt;
  }

  /**
   * The optional grouping-size specifies the size (normally 3) of the grouping.
   * @serial
   */
  private AVT m_groupingSize_avt = null;

  /**
   * Set the "grouping-size" attribute.
   * The optional grouping-size specifies the size (normally 3) of the grouping.
   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
   *
   * @param v Value to set for "grouping-size" attribute.
   */
  public void setGroupingSize(AVT v)
  {
    m_groupingSize_avt = v;
  }

  /**
   * Get the "grouping-size" attribute.
   * The optional grouping-size specifies the size (normally 3) of the grouping.
   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
   *
   * @return Value of "grouping-size" attribute.
   */
  public AVT getGroupingSize()
  {
    return m_groupingSize_avt;
  }

  /**
   * Shouldn't this be in the transformer?  Big worries about threads...
   */

  // private XResourceBundle thisBundle;

  /**
   * Table to help in converting decimals to roman numerals.
   * @see org.apache.xalan.transformer.DecimalToRoman
   */
  private final static DecimalToRoman m_romanConvertTable[] = {
    new DecimalToRoman(1000, "M", 900, "CM"),
    new DecimalToRoman(500, "D", 400, "CD"),
    new DecimalToRoman(100L, "C", 90L, "XC"),
    new DecimalToRoman(50L, "L", 40L, "XL"),
    new DecimalToRoman(10L, "X", 9L, "IX"),
    new DecimalToRoman(5L, "V", 4L, "IV"),
    new DecimalToRoman(1L, "I", 1L, "I") };
  
  /**
   * This function is called after everything else has been
   * recomposed, and allows the template to set remaining
   * values that may be based on some other property that
   * depends on recomposition.
   */
  public void compose(StylesheetRoot sroot) throws TransformerException
  {
    super.compose(sroot);
    StylesheetRoot.ComposeState cstate = sroot.getComposeState();
    java.util.Vector vnames = cstate.getVariableNames();
    if(null != m_countMatchPattern)
      m_countMatchPattern.fixupVariables(vnames, cstate.getGlobalsSize());
    if(null != m_format_avt)
      m_format_avt.fixupVariables(vnames, cstate.getGlobalsSize());
    if(null != m_fromMatchPattern)
      m_fromMatchPattern.fixupVariables(vnames, cstate.getGlobalsSize());
    if(null != m_groupingSeparator_avt)
      m_groupingSeparator_avt.fixupVariables(vnames, cstate.getGlobalsSize());
    if(null != m_groupingSize_avt)
      m_groupingSize_avt.fixupVariables(vnames, cstate.getGlobalsSize());
    if(null != m_lang_avt)
      m_lang_avt.fixupVariables(vnames, cstate.getGlobalsSize());
    if(null != m_lettervalue_avt)
      m_lettervalue_avt.fixupVariables(vnames, cstate.getGlobalsSize());
    if(null != m_valueExpr)
      m_valueExpr.fixupVariables(vnames, cstate.getGlobalsSize());
  }


  /**
   * Get an int constant identifying the type of element.
   * @see org.apache.xalan.templates.Constants
   *
   * @return The token ID for this element
   */
  public int getXSLToken()
  {
    return Constants.ELEMNAME_NUMBER;
  }

  /**
   * Return the node name.
   *
   * @return The element's name
   */
  public String getNodeName()
  {
    return Constants.ELEMNAME_NUMBER_STRING;
  }

  /**
   * Execute an xsl:number instruction. The xsl:number element is
   * used to insert a formatted number into the result tree.
   *
   * @param transformer non-null reference to the the current transform-time state.
   *
   * @throws TransformerException
   */
  public void execute(
          TransformerImpl transformer)
            throws TransformerException
  {

     if (transformer.getDebug())
      transformer.getTraceManager().fireTraceEvent(this);

    int sourceNode = transformer.getXPathContext().getCurrentNode();
    String countString = getCountString(transformer, sourceNode);

    try
    {
      transformer.getResultTreeHandler().characters(countString.toCharArray(),
                                                    0, countString.length());
    }
    catch(SAXException se)
    {
      throw new TransformerException(se);
    }
    finally
    {
      if (transformer.getDebug())
	    transformer.getTraceManager().fireTraceEndEvent(this); 
    }
  }

  /**
   * Add a child to the child list.
   *
   * @param newChild Child to add to child list
   *
   * @return Child just added to child list
   *
   * @throws DOMException
   */
  public ElemTemplateElement appendChild(ElemTemplateElement newChild)
  {

    error(XSLTErrorResources.ER_CANNOT_ADD,
          new Object[]{ newChild.getNodeName(),
                        this.getNodeName() });  //"Can not add " +((ElemTemplateElement)newChild).m_elemName +

    //" to " + this.m_elemName);
    return null;
  }

  /**
   * Given a 'from' pattern (ala xsl:number), a match pattern
   * and a context, find the first ancestor that matches the
   * pattern (including the context handed in).
   *
   * @param xctxt The XPath runtime state for this.
   * @param fromMatchPattern The ancestor must match this pattern.
   * @param countMatchPattern The ancestor must also match this pattern.
   * @param context The node that "." expresses.
   * @param namespaceContext The context in which namespaces in the
   * queries are supposed to be expanded.
   *
   * @return the first ancestor that matches the given pattern
   *
   * @throws javax.xml.transform.TransformerException
   */
  int findAncestor(
          XPathContext xctxt, XPath fromMatchPattern, XPath countMatchPattern, 
          int context, ElemNumber namespaceContext)
            throws javax.xml.transform.TransformerException
  {
    DTM dtm = xctxt.getDTM(context);
    while (DTM.NULL != context)
    {
      if (null != fromMatchPattern)
      {
        if (fromMatchPattern.getMatchScore(xctxt, context)
                != XPath.MATCH_SCORE_NONE)
        {

          //context = null;
          break;
        }
      }

      if (null != countMatchPattern)
      {
        if (countMatchPattern.getMatchScore(xctxt, context)
                != XPath.MATCH_SCORE_NONE)
        {
          break;
        }
      }

      context = dtm.getParent(context);
    }

    return context;
  }

  /**
   * Given a 'from' pattern (ala xsl:number), a match pattern
   * and a context, find the first ancestor that matches the
   * pattern (including the context handed in).
   * @param xctxt The XPath runtime state for this.
   * @param fromMatchPattern The ancestor must match this pattern.
   * @param countMatchPattern The ancestor must also match this pattern.
   * @param context The node that "." expresses.
   * @param namespaceContext The context in which namespaces in the
   * queries are supposed to be expanded.
   *
   * @return the first preceding, ancestor or self node that 
   * matches the given pattern
   *
   * @throws javax.xml.transform.TransformerException
   */
  private int findPrecedingOrAncestorOrSelf(
          XPathContext xctxt, XPath fromMatchPattern, XPath countMatchPattern, 
          int context, ElemNumber namespaceContext)
            throws javax.xml.transform.TransformerException
  {
    DTM dtm = xctxt.getDTM(context);
    while (DTM.NULL != context)
    {
      if (null != fromMatchPattern)
      {
        if (fromMatchPattern.getMatchScore(xctxt, context)
                != XPath.MATCH_SCORE_NONE)
        {
          context = DTM.NULL;

          break;
        }
      }

      if (null != countMatchPattern)
      {
        if (countMatchPattern.getMatchScore(xctxt, context)
                != XPath.MATCH_SCORE_NONE)
        {
          break;
        }
      }

      int prevSibling = dtm.getPreviousSibling(context);

      if (DTM.NULL == prevSibling)
      {
        context = dtm.getParent(context);
      }
      else
      {

        // Now go down the chain of children of this sibling 
        context = dtm.getLastChild(prevSibling);

        if (context == DTM.NULL)
          context = prevSibling;
      }
    }

    return context;
  }

  /**
   * Get the count match pattern, or a default value.
   *
   * @param support The XPath runtime state for this.
   * @param contextNode The node that "." expresses.
   *
   * @return the count match pattern, or a default value. 
   *
   * @throws javax.xml.transform.TransformerException
   */
  XPath getCountMatchPattern(XPathContext support, int contextNode)
          throws javax.xml.transform.TransformerException
  {

    XPath countMatchPattern = m_countMatchPattern;
    DTM dtm = support.getDTM(contextNode);
    if (null == countMatchPattern)
    {
      switch (dtm.getNodeType(contextNode))
      {
      case DTM.ELEMENT_NODE :
        MyPrefixResolver resolver;

        if (dtm.getNamespaceURI(contextNode) == null) {
             resolver =  new MyPrefixResolver(dtm.getNode(contextNode), dtm,contextNode, false);
        } else {
            resolver = new MyPrefixResolver(dtm.getNode(contextNode), dtm,contextNode, true);
        }

        countMatchPattern = new XPath(dtm.getNodeName(contextNode), this, resolver,
                                      XPath.MATCH, support.getErrorListener());
        break;

      case DTM.ATTRIBUTE_NODE :

        // countMatchPattern = m_stylesheet.createMatchPattern("@"+contextNode.getNodeName(), this);
        countMatchPattern = new XPath("@" + dtm.getNodeName(contextNode), this,
                                      this, XPath.MATCH, support.getErrorListener());
        break;
      case DTM.CDATA_SECTION_NODE :
      case DTM.TEXT_NODE :

        // countMatchPattern = m_stylesheet.createMatchPattern("text()", this);
        countMatchPattern = new XPath("text()", this, this, XPath.MATCH, support.getErrorListener());
        break;
      case DTM.COMMENT_NODE :

        // countMatchPattern = m_stylesheet.createMatchPattern("comment()", this);
        countMatchPattern = new XPath("comment()", this, this, XPath.MATCH, support.getErrorListener());
        break;
      case DTM.DOCUMENT_NODE :

        // countMatchPattern = m_stylesheet.createMatchPattern("/", this);
        countMatchPattern = new XPath("/", this, this, XPath.MATCH, support.getErrorListener());
        break;
      case DTM.PROCESSING_INSTRUCTION_NODE :

        // countMatchPattern = m_stylesheet.createMatchPattern("pi("+contextNode.getNodeName()+")", this);
        countMatchPattern = new XPath("pi(" + dtm.getNodeName(contextNode)
                                      + ")", this, this, XPath.MATCH, support.getErrorListener());
        break;
      default :
        countMatchPattern = null;
      }
    }

    return countMatchPattern;
  }

  /**
   * Given an XML source node, get the count according to the
   * parameters set up by the xsl:number attributes.
   * @param transformer non-null reference to the the current transform-time state.
   * @param sourceNode The source node being counted.
   *
   * @return The count of nodes
   *
   * @throws TransformerException
   */
  String getCountString(TransformerImpl transformer, int sourceNode)
          throws TransformerException
  {

    long[] list = null;
    XPathContext xctxt = transformer.getXPathContext();
    CountersTable ctable = transformer.getCountersTable();

    if (null != m_valueExpr)
    {
      XObject countObj = m_valueExpr.execute(xctxt, sourceNode, this);
      //According to Errata E24
      double d_count = java.lang.Math.floor(countObj.num()+ 0.5);
      if (Double.isNaN(d_count)) return "NaN";
      else if (d_count < 0 && Double.isInfinite(d_count)) return "-Infinity";
      else if (Double.isInfinite(d_count)) return "Infinity";
      else if (d_count == 0) return "0";
      else{
              long count = (long)d_count;
              list = new long[1];
              list[0] = count;              
      }
    }
    else
    {
      if (Constants.NUMBERLEVEL_ANY == m_level)
      {
        list = new long[1];
        list[0] = ctable.countNode(xctxt, this, sourceNode);
      }
      else
      {
        NodeVector ancestors =
          getMatchingAncestors(xctxt, sourceNode,
                               Constants.NUMBERLEVEL_SINGLE == m_level);
        int lastIndex = ancestors.size() - 1;

        if (lastIndex >= 0)
        {
          list = new long[lastIndex + 1];

          for (int i = lastIndex; i >= 0; i--)
          {
            int target = ancestors.elementAt(i);

            list[lastIndex - i] = ctable.countNode(xctxt, this, target);
          }
        }
      }
    }

    return (null != list)
           ? formatNumberList(transformer, list, sourceNode) : "";
  }

  /**
   * Get the previous node to be counted.
   *
   * @param xctxt The XPath runtime state for this.
   * @param pos The current node
   *
   * @return the previous node to be counted.
   *
   * @throws TransformerException
   */
  public int getPreviousNode(XPathContext xctxt, int pos)
          throws TransformerException
  {

    XPath countMatchPattern = getCountMatchPattern(xctxt, pos);
    DTM dtm = xctxt.getDTM(pos);

    if (Constants.NUMBERLEVEL_ANY == m_level)
    {
      XPath fromMatchPattern = m_fromMatchPattern;

      // Do a backwards document-order walk 'till a node is found that matches 
      // the 'from' pattern, or a node is found that matches the 'count' pattern, 
      // or the top of the tree is found.
      while (DTM.NULL != pos)
      {

        // Get the previous sibling, if there is no previous sibling, 
        // then count the parent, but if there is a previous sibling, 
        // dive down to the lowest right-hand (last) child of that sibling.
        int next = dtm.getPreviousSibling(pos);

        if (DTM.NULL == next)
        {
          next = dtm.getParent(pos);

          if ((DTM.NULL != next) && ((((null != fromMatchPattern) && (fromMatchPattern.getMatchScore(
                  xctxt, next) != XPath.MATCH_SCORE_NONE))) 
              || (dtm.getNodeType(next) == DTM.DOCUMENT_NODE)))
          {
            pos = DTM.NULL;  // return null from function.

            break;  // from while loop
          }
        }
        else
        {

          // dive down to the lowest right child.
          int child = next;

          while (DTM.NULL != child)
          {
            child = dtm.getLastChild(next);

            if (DTM.NULL != child)
              next = child;
          }
        }

        pos = next;

        if ((DTM.NULL != pos)
                && ((null == countMatchPattern)
                    || (countMatchPattern.getMatchScore(xctxt, pos)
                        != XPath.MATCH_SCORE_NONE)))
        {
          break;
        }
      }
    }
    else  // NUMBERLEVEL_MULTI or NUMBERLEVEL_SINGLE
    {
      while (DTM.NULL != pos)
      {
        pos = dtm.getPreviousSibling(pos);

        if ((DTM.NULL != pos)
                && ((null == countMatchPattern)
                    || (countMatchPattern.getMatchScore(xctxt, pos)
                        != XPath.MATCH_SCORE_NONE)))
        {
          break;
        }
      }
    }

    return pos;
  }

  /**
   * Get the target node that will be counted..
   *
   * @param xctxt The XPath runtime state for this.
   * @param sourceNode non-null reference to the <a href="http://www.w3.org/TR/xslt#dt-current-node">current source node</a>.
   *
   * @return the target node that will be counted
   *
   * @throws TransformerException
   */
  public int getTargetNode(XPathContext xctxt, int sourceNode)
          throws TransformerException
  {

    int target = DTM.NULL;
    XPath countMatchPattern = getCountMatchPattern(xctxt, sourceNode);

    if (Constants.NUMBERLEVEL_ANY == m_level)
    {
      target = findPrecedingOrAncestorOrSelf(xctxt, m_fromMatchPattern,
                                             countMatchPattern, sourceNode,
                                             this);
    }
    else
    {
      target = findAncestor(xctxt, m_fromMatchPattern, countMatchPattern,
                            sourceNode, this);
    }

    return target;
  }

  /**
   * Get the ancestors, up to the root, that match the
   * pattern.
   * 
   * @param xctxt The XPath runtime state for this.
   * @param node Count this node and it's ancestors.
   * @param stopAtFirstFound Flag indicating to stop after the
   * first node is found (difference between level = single
   * or multiple)
   * @return The number of ancestors that match the pattern.
   *
   * @throws javax.xml.transform.TransformerException
   */
  NodeVector getMatchingAncestors(
          XPathContext xctxt, int node, boolean stopAtFirstFound)
            throws javax.xml.transform.TransformerException
  {

    NodeSetDTM ancestors = new NodeSetDTM(xctxt.getDTMManager());
    XPath countMatchPattern = getCountMatchPattern(xctxt, node);
    DTM dtm = xctxt.getDTM(node);

    while (DTM.NULL != node)
    {
      if ((null != m_fromMatchPattern)
              && (m_fromMatchPattern.getMatchScore(xctxt, node)
                  != XPath.MATCH_SCORE_NONE))
      {

        // The following if statement gives level="single" different 
        // behavior from level="multiple", which seems incorrect according 
        // to the XSLT spec.  For now we are leaving this in to replicate 
        // the same behavior in XT, but, for all intents and purposes we 
        // think this is a bug, or there is something about level="single" 
        // that we still don't understand.
        if (!stopAtFirstFound)
          break;
      }

      if (null == countMatchPattern)
        System.out.println(
          "Programmers error! countMatchPattern should never be null!");

      if (countMatchPattern.getMatchScore(xctxt, node)
              != XPath.MATCH_SCORE_NONE)
      {
        ancestors.addElement(node);

        if (stopAtFirstFound)
          break;
      }

      node = dtm.getParent(node);
    }

    return ancestors;
  }  // end getMatchingAncestors method

  /**
   * Get the locale we should be using.
   *
   * @param transformer non-null reference to the the current transform-time state.
   * @param contextNode The node that "." expresses.
   *
   * @return The locale to use. May be specified by "lang" attribute,
   * but if not, use default locale on the system. 
   *
   * @throws TransformerException
   */
  Locale getLocale(TransformerImpl transformer, int contextNode)
          throws TransformerException
  {

    Locale locale = null;

    if (null != m_lang_avt)
    {
      XPathContext xctxt = transformer.getXPathContext();
      String langValue = m_lang_avt.evaluate(xctxt, contextNode, this);

      if (null != langValue)
      {

        // Not really sure what to do about the country code, so I use the
        // default from the system.
        // TODO: fix xml:lang handling.
        locale = new Locale(langValue.toUpperCase(), "");

        //Locale.getDefault().getDisplayCountry());
        if (null == locale)
        {
          transformer.getMsgMgr().warn(this, null, xctxt.getDTM(contextNode).getNode(contextNode),
                                       XSLTErrorResources.WG_LOCALE_NOT_FOUND,
                                       new Object[]{ langValue });  //"Warning: Could not find locale for xml:lang="+langValue);

          locale = Locale.getDefault();
        }
      }
    }
    else
    {
      locale = Locale.getDefault();
    }

    return locale;
  }

  /**
   * Get the number formatter to be used the format the numbers
   *
   * @param transformer non-null reference to the the current transform-time state.
   * @param contextNode The node that "." expresses.
   *
   * ($objectName$) @return The number formatter to be used
   *
   * @throws TransformerException
   */
  private DecimalFormat getNumberFormatter(
          TransformerImpl transformer, int contextNode) throws TransformerException
  {
    // Patch from Steven Serocki
    // Maybe we really want to do the clone in getLocale() and return  
    // a clone of the default Locale??
    Locale locale = (Locale)getLocale(transformer, contextNode).clone();

    // Helper to format local specific numbers to strings.
    DecimalFormat formatter = null;

    //synchronized (locale)
    //{
    //     formatter = (DecimalFormat) NumberFormat.getNumberInstance(locale);
    //}

    String digitGroupSepValue =
      (null != m_groupingSeparator_avt)
      ? m_groupingSeparator_avt.evaluate(
      transformer.getXPathContext(), contextNode, this) : null;
      
      
    // Validate grouping separator if an AVT was used; otherwise this was 
    // validated statically in XSLTAttributeDef.java.
    if ((digitGroupSepValue != null) && (!m_groupingSeparator_avt.isSimple()) &&
        (digitGroupSepValue.length() != 1))
    {
            transformer.getMsgMgr().warn(
               this, XSLTErrorResources.WG_ILLEGAL_ATTRIBUTE_VALUE,
               new Object[]{ Constants.ATTRNAME_NAME, m_groupingSeparator_avt.getName()});   
    }                  
      
      
    String nDigitsPerGroupValue =
      (null != m_groupingSize_avt)
      ? m_groupingSize_avt.evaluate(
      transformer.getXPathContext(), contextNode, this) : null;

    // TODO: Handle digit-group attributes
    if ((null != digitGroupSepValue) && (null != nDigitsPerGroupValue) &&
        // Ignore if separation value is empty string
        (digitGroupSepValue.length() > 0))
    {
      try
      {
        formatter = (DecimalFormat) NumberFormat.getNumberInstance(locale);
        formatter.setGroupingSize(
          Integer.valueOf(nDigitsPerGroupValue).intValue());
        
        DecimalFormatSymbols symbols = formatter.getDecimalFormatSymbols();
        symbols.setGroupingSeparator(digitGroupSepValue.charAt(0));
        formatter.setDecimalFormatSymbols(symbols);
        formatter.setGroupingUsed(true);
      }
      catch (NumberFormatException ex)
      {
        formatter.setGroupingUsed(false);
      }
    }

    return formatter;
  }

  /**
   * Format a vector of numbers into a formatted string.
   * 
   * @param transformer non-null reference to the the current transform-time state.
   * @param list Array of one or more long integer numbers.
   * @param contextNode The node that "." expresses.
   * @return String that represents list according to
   * %conversion-atts; attributes.
   * TODO: Optimize formatNumberList so that it caches the last count and
   * reuses that info for the next count.
   *
   * @throws TransformerException
   */
  String formatNumberList(
          TransformerImpl transformer, long[] list, int contextNode)
            throws TransformerException
  {

    String numStr;
    FastStringBuffer formattedNumber = StringBufferPool.get();

    try
    {
      int nNumbers = list.length, numberWidth = 1;
      char numberType = '1';
      String formatToken, lastSepString = null, formatTokenString = null;

      // If a seperator hasn't been specified, then use "."  
      // as a default separator. 
      // For instance: [2][1][5] with a format value of "1 "
      // should format to "2.1.5 " (I think).
      // Otherwise, use the seperator specified in the format string.
      // For instance: [2][1][5] with a format value of "01-001. "
      // should format to "02-001-005 ".
      String lastSep = ".";
      boolean isFirstToken = true;  // true if first token  
      String formatValue =
        (null != m_format_avt)
        ? m_format_avt.evaluate(
        transformer.getXPathContext(), contextNode, this) : null;

      if (null == formatValue)
        formatValue = "1";

      NumberFormatStringTokenizer formatTokenizer =
        new NumberFormatStringTokenizer(formatValue);

      // int sepCount = 0;                  // keep track of seperators
      // Loop through all the numbers in the list.
      for (int i = 0; i < nNumbers; i++)
      {

        // Loop to the next digit, letter, or separator.
        if (formatTokenizer.hasMoreTokens())
        {
          formatToken = formatTokenizer.nextToken();

          // If the first character of this token is a character or digit, then 
          // it is a number format directive.
          if (Character.isLetterOrDigit(
                  formatToken.charAt(formatToken.length() - 1)))
          {
            numberWidth = formatToken.length();
            numberType = formatToken.charAt(numberWidth - 1);
          }

          // If there is a number format directive ahead, 
          // then append the formatToken.
          else if (formatTokenizer.isLetterOrDigitAhead())
          {
            final StringBuffer formatTokenStringBuffer = new StringBuffer(formatToken);

            // Append the formatToken string...
            // For instance [2][1][5] with a format value of "1--1. "
            // should format to "2--1--5. " (I guess).
            while (formatTokenizer.nextIsSep())
            {
              formatToken = formatTokenizer.nextToken();
              formatTokenStringBuffer.append(formatToken);
            }
            formatTokenString = formatTokenStringBuffer.toString();

            // Record this separator, so it can be used as the 
            // next separator, if the next is the last.
            // For instance: [2][1][5] with a format value of "1-1 "
            // should format to "2-1-5 ".
            if (!isFirstToken)
              lastSep = formatTokenString;

            // Since we know the next is a number or digit, we get it now.
            formatToken = formatTokenizer.nextToken();
            numberWidth = formatToken.length();
            numberType = formatToken.charAt(numberWidth - 1);
          }
          else  // only separators left
          {

            // Set up the string for the trailing characters after 
            // the last number is formatted (i.e. after the loop).
            lastSepString = formatToken;

            // And append any remaining characters to the lastSepString.
            while (formatTokenizer.hasMoreTokens())
            {
              formatToken = formatTokenizer.nextToken();
              lastSepString += formatToken;
            }
          }  // else
        }  // end if(formatTokenizer.hasMoreTokens())

        // if this is the first token and there was a prefix
        // append the prefix else, append the separator
        // For instance, [2][1][5] with a format value of "(1-1.) "
        // should format to "(2-1-5.) " (I guess).
        if (null != formatTokenString && isFirstToken)
        {
          formattedNumber.append(formatTokenString);
        }
        else if (null != lastSep &&!isFirstToken)
          formattedNumber.append(lastSep);

        getFormattedNumber(transformer, contextNode, numberType, numberWidth,
                           list[i], formattedNumber);

        isFirstToken = false;  // After the first pass, this should be false
      }  // end for loop

      // Check to see if we finished up the format string...
      // Skip past all remaining letters or digits
      while (formatTokenizer.isLetterOrDigitAhead())
      {
        formatTokenizer.nextToken();
      }

      if (lastSepString != null)
        formattedNumber.append(lastSepString);

      while (formatTokenizer.hasMoreTokens())
      {
        formatToken = formatTokenizer.nextToken();

        formattedNumber.append(formatToken);
      }

      numStr = formattedNumber.toString();
    }
    finally
    {
      StringBufferPool.free(formattedNumber);
    }

    return numStr;
  }  // end formatNumberList method

  /*
  * Get Formatted number
  */

  /**
   * Format the given number and store it in the given buffer 
   *
   *
   * @param transformer non-null reference to the the current transform-time state.
   * @param contextNode The node that "." expresses.
   * @param numberType Type to format to
   * @param numberWidth Maximum length of formatted number
   * @param listElement Number to format
   * @param formattedNumber Buffer to store formatted number
   *
   * @throws javax.xml.transform.TransformerException
   */
  private void getFormattedNumber(
          TransformerImpl transformer, int contextNode, 
          char numberType, int numberWidth, long listElement, 
          FastStringBuffer formattedNumber)
            throws javax.xml.transform.TransformerException
  {


    String letterVal =
      (m_lettervalue_avt != null)
      ? m_lettervalue_avt.evaluate(
      transformer.getXPathContext(), contextNode, this) : null;

    /**
     * Wrapper of Chars for converting integers into alpha counts.
     */
    CharArrayWrapper alphaCountTable = null;
    
    XResourceBundle thisBundle = null;
     
    switch (numberType)
    {
    case 'A' :
        if (null == m_alphaCountTable){
                thisBundle =
                  (XResourceBundle) XResourceBundle.loadResourceBundle(
                    org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, getLocale(transformer, contextNode));
                m_alphaCountTable = (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET);                
        }
      int2alphaCount(listElement, m_alphaCountTable, formattedNumber);
      break;
    case 'a' :
        if (null == m_alphaCountTable){
                thisBundle =
                  (XResourceBundle) XResourceBundle.loadResourceBundle(
                    org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, getLocale(transformer, contextNode));
                m_alphaCountTable = (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET);                
        }
      FastStringBuffer stringBuf = StringBufferPool.get();

      try
      {
        int2alphaCount(listElement, m_alphaCountTable, stringBuf);
        formattedNumber.append(
          stringBuf.toString().toLowerCase(
            getLocale(transformer, contextNode)));
      }
      finally
      {
        StringBufferPool.free(stringBuf);
      }
      break;
    case 'I' :
      formattedNumber.append(long2roman(listElement, true));
      break;
    case 'i' :
      formattedNumber.append(
        long2roman(listElement, true).toLowerCase(
          getLocale(transformer, contextNode)));
      break;
    case 0x3042 :
    {

      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("ja", "JP", "HA"));

      if (letterVal != null
              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
        formattedNumber.append(
          int2singlealphaCount(
            listElement,
            (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET)));

      break;
    }
    case 0x3044 :
    {

      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("ja", "JP", "HI"));

      if ((letterVal != null)
              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
        formattedNumber.append(
          int2singlealphaCount(
            listElement,
            (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET)));

      break;
    }
    case 0x30A2 :
    {

      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("ja", "JP", "A"));

      if (letterVal != null
              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
        formattedNumber.append(
          int2singlealphaCount(
            listElement,
            (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET)));

      break;
    }
    case 0x30A4 :
    {

      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("ja", "JP", "I"));

      if (letterVal != null
              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
        formattedNumber.append(
          int2singlealphaCount(
            listElement,
            (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET)));

      break;
    }
    case 0x4E00 :
    {

      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("zh", "CN"));

      if (letterVal != null
              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
      {
        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
      }
      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
        int2alphaCount(listElement,
                       (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET),
                       formattedNumber);

      break;
    }
    case 0x58F9 :
    {

      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("zh", "TW"));

      if (letterVal != null
              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
        int2alphaCount(listElement,
                       (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET),
                       formattedNumber);

      break;
    }
    case 0x0E51 :
    {

      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("th", ""));

      if (letterVal != null
              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
        int2alphaCount(listElement,
                       (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET),
                       formattedNumber);

      break;
    }
    case 0x05D0 :
    {

      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("he", ""));

      if (letterVal != null
              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
        int2alphaCount(listElement,
                       (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET),
                       formattedNumber);

      break;
    }
    case 0x10D0 :
    {

      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("ka", ""));

      if (letterVal != null
              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
        int2alphaCount(listElement,
                       (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET),
                       formattedNumber);

      break;
    }
    case 0x03B1 :
    {

      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("el", ""));

      if (letterVal != null
              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
        int2alphaCount(listElement,
                       (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET),
                       formattedNumber);

      break;
    }
    case 0x0430 :
    {

      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("cy", ""));

      if (letterVal != null
              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
        int2alphaCount(listElement,
                       (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET),
                       formattedNumber);

      break;
    }
    default :  // "1"
      DecimalFormat formatter = getNumberFormatter(transformer, contextNode);
      String padString = formatter == null ? String.valueOf(0) : formatter.format(0);    
      String numString = formatter == null ? String.valueOf(listElement) : formatter.format(listElement);
      int nPadding = numberWidth - numString.length();

      for (int k = 0; k < nPadding; k++)
      {
        formattedNumber.append(padString);
      }

      formattedNumber.append(numString);
    }
  }
  
  /**
   * Get a string value for zero, which is not really defined by the 1.0 spec, 
   * thought I think it might be cleared up by the erreta.
   */
   String getZeroString()
   {
     return ""+0;
   }

  /**
   * Convert a long integer into alphabetic counting, in other words
   * count using the sequence A B C ... Z.
   * 
   * @param val Value to convert -- must be greater than zero.
   * @param table a table containing one character for each digit in the radix
   * @return String representing alpha count of number.
   * @see TransformerImpl#DecimalToRoman
   *
   * Note that the radix of the conversion is inferred from the size
   * of the table.
   */
  protected String int2singlealphaCount(long val, CharArrayWrapper table)
  {

    int radix = table.getLength();

    // TODO:  throw error on out of range input
    if (val > radix)
    {
      return getZeroString();
    }
    else
      return (new Character(table.getChar((int)val - 1))).toString();  // index into table is off one, starts at 0
  }

  /**
   * Convert a long integer into alphabetic counting, in other words
   * count using the sequence A B C ... Z AA AB AC.... etc.
   * 
   * @param val Value to convert -- must be greater than zero.
   * @param table a table containing one character for each digit in the radix
   * @param aTable Array of alpha characters representing numbers
   * @param stringBuf Buffer where to save the string representing alpha count of number.
   * 
   * @see TransformerImpl#DecimalToRoman
   *
   * Note that the radix of the conversion is inferred from the size
   * of the table.
   */
  protected void int2alphaCount(long val, CharArrayWrapper aTable,
                                FastStringBuffer stringBuf)
  {

    int radix = aTable.getLength();
    char[] table = new char[radix];

    // start table at 1, add last char at index 0. Reason explained above and below.
    int i;

    for (i = 0; i < radix - 1; i++)
    {
      table[i + 1] = aTable.getChar(i);
    }

    table[0] = aTable.getChar(i);

    // Create a buffer to hold the result
    // TODO:  size of the table can be detereined by computing
    // logs of the radix.  For now, we fake it.
    char buf[] = new char[100];

    //some languages go left to right(ie. english), right to left (ie. Hebrew),
    //top to bottom (ie.Japanese), etc... Handle them differently
    //String orientation = thisBundle.getString(org.apache.xml.utils.res.XResourceBundle.LANG_ORIENTATION);
    // next character to set in the buffer
    int charPos;

    charPos = buf.length - 1;  // work backward through buf[]  

    // index in table of the last character that we stored
    int lookupIndex = 1;  // start off with anything other than zero to make correction work

    //                                          Correction number
    //
    //  Correction can take on exactly two values:
    //
    //          0       if the next character is to be emitted is usual
    //
    //      radix - 1
    //                  if the next char to be emitted should be one less than
    //                  you would expect
    //                  
    // For example, consider radix 10, where 1="A" and 10="J"
    //
    // In this scheme, we count: A, B, C ...   H, I, J (not A0 and certainly
    // not AJ), A1
    //
    // So, how do we keep from emitting AJ for 10?  After correctly emitting the
    // J, lookupIndex is zero.  We now compute a correction number of 9 (radix-1).
    // In the following line, we'll compute (val+correction) % radix, which is,
    // (val+9)/10.  By this time, val is 1, so we compute (1+9) % 10, which
    // is 10 % 10 or zero.  So, we'll prepare to emit "JJ", but then we'll
    // later suppress the leading J as representing zero (in the mod system,
    // it can represent either 10 or zero).  In summary, the correction value of
    // "radix-1" acts like "-1" when run through the mod operator, but with the
    // desireable characteristic that it never produces a negative number.
    long correction = 0;

    // TODO:  throw error on out of range input
    do
    {

      // most of the correction calculation is explained above,  the reason for the
      // term after the "|| " is that it correctly propagates carries across
      // multiple columns.
      correction =
        ((lookupIndex == 0) || (correction != 0 && lookupIndex == radix - 1))
        ? (radix - 1) : 0;

      // index in "table" of the next char to emit
      lookupIndex = (int)(val + correction) % radix;

      // shift input by one "column"
      val = (val / radix);

      // if the next value we'd put out would be a leading zero, we're done.
      if (lookupIndex == 0 && val == 0)
        break;

      // put out the next character of output
      buf[charPos--] = table[lookupIndex];  // left to right or top to bottom   
    }
    while (val > 0);

    stringBuf.append(buf, charPos + 1, (buf.length - charPos - 1));
  }

  /**
   * Convert a long integer into traditional alphabetic counting, in other words
   * count using the traditional numbering.
   * 
   * @param val Value to convert -- must be greater than zero.
   * @param thisBundle Resource bundle to use
   * 
   * @return String representing alpha count of number.
   * @see XSLProcessor#DecimalToRoman
   *
   * Note that the radix of the conversion is inferred from the size
   * of the table.
   */
  protected String tradAlphaCount(long val, XResourceBundle thisBundle)
  {

    // if this number is larger than the largest number we can represent, error!
    if (val > Long.MAX_VALUE)
    {
      this.error(XSLTErrorResources.ER_NUMBER_TOO_BIG);
      return XSLTErrorResources.ERROR_STRING;
    }
    char[] table = null;

    // index in table of the last character that we stored
    int lookupIndex = 1;  // start off with anything other than zero to make correction work

    // Create a buffer to hold the result
    // TODO:  size of the table can be detereined by computing
    // logs of the radix.  For now, we fake it.
    char buf[] = new char[100];

    //some languages go left to right(ie. english), right to left (ie. Hebrew),
    //top to bottom (ie.Japanese), etc... Handle them differently
    //String orientation = thisBundle.getString(org.apache.xml.utils.res.XResourceBundle.LANG_ORIENTATION);
    // next character to set in the buffer
    int charPos;

    charPos = 0;  //start at 0

    // array of number groups: ie.1000, 100, 10, 1
    IntArrayWrapper groups = (IntArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_NUMBERGROUPS);

    // array of tables of hundreds, tens, digits...
    StringArrayWrapper tables =
      (StringArrayWrapper) (thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_NUM_TABLES));

    //some languages have additive alphabetical notation,
    //some multiplicative-additive, etc... Handle them differently.
    String numbering = thisBundle.getString(org.apache.xml.utils.res.XResourceBundle.LANG_NUMBERING);

    // do multiplicative part first
    if (numbering.equals(org.apache.xml.utils.res.XResourceBundle.LANG_MULT_ADD))
    {
      String mult_order = thisBundle.getString(org.apache.xml.utils.res.XResourceBundle.MULT_ORDER);
      LongArrayWrapper multiplier =
        (LongArrayWrapper) (thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_MULTIPLIER));
      CharArrayWrapper zeroChar = (CharArrayWrapper) thisBundle.getObject("zero");
      int i = 0;

      // skip to correct multiplier
      while (i < multiplier.getLength() && val < multiplier.getLong(i))
      {
        i++;
      }

      do
      {
        if (i >= multiplier.getLength())
          break;  //number is smaller than multipliers

        // some languages (ie chinese) put a zero character (and only one) when
        // the multiplier is multiplied by zero. (ie, 1001 is 1X1000 + 0X100 + 0X10 + 1)
        // 0X100 is replaced by the zero character, we don't need one for 0X10
        if (val < multiplier.getLong(i))
        {
          if (zeroChar.getLength() == 0)
          {
            i++;
          }
          else
          {
            if (buf[charPos - 1] != zeroChar.getChar(0))
              buf[charPos++] = zeroChar.getChar(0);

            i++;
          }
        }
        else if (val >= multiplier.getLong(i))
        {
          long mult = val / multiplier.getLong(i);

          val = val % multiplier.getLong(i);  // save this.

          int k = 0;

          while (k < groups.getLength())
          {
            lookupIndex = 1;  // initialize for each table

            if (mult / groups.getInt(k) <= 0)  // look for right table
              k++;
            else
            {

              // get the table
              CharArrayWrapper THEletters = (CharArrayWrapper) thisBundle.getObject(tables.getString(k));

              table = new char[THEletters.getLength() + 1];

              int j;

              for (j = 0; j < THEletters.getLength(); j++)
              {
                table[j + 1] = THEletters.getChar(j);
              }

              table[0] = THEletters.getChar(j - 1);  // don't need this                                                                         

              // index in "table" of the next char to emit
              lookupIndex = (int)mult / groups.getInt(k);

              //this should not happen
              if (lookupIndex == 0 && mult == 0)
                break;

              char multiplierChar = ((CharArrayWrapper) (thisBundle.getObject(
                org.apache.xml.utils.res.XResourceBundle.LANG_MULTIPLIER_CHAR))).getChar(i);

              // put out the next character of output   
              if (lookupIndex < table.length)
              {
                if (mult_order.equals(org.apache.xml.utils.res.XResourceBundle.MULT_PRECEDES))
                {
                  buf[charPos++] = multiplierChar;
                  buf[charPos++] = table[lookupIndex];
                }
                else
                {

                  // don't put out 1 (ie 1X10 is just 10)
                  if (lookupIndex == 1 && i == multiplier.getLength() - 1){}
                  else
                    buf[charPos++] = table[lookupIndex];

                  buf[charPos++] = multiplierChar;
                }

                break;  // all done!
              }
              else
                return XSLTErrorResources.ERROR_STRING;
            }  //end else
          }  // end while        

          i++;
        }  // end else if
      }  // end do while
      while (i < multiplier.getLength());
    }

    // Now do additive part...
    int count = 0;
    String tableName;

    // do this for each table of hundreds, tens, digits...
    while (count < groups.getLength())
    {
      if (val / groups.getInt(count) <= 0)  // look for correct table
        count++;
      else
      {
        CharArrayWrapper theletters = (CharArrayWrapper) thisBundle.getObject(tables.getString(count));

        table = new char[theletters.getLength() + 1];

        int j;

        // need to start filling the table up at index 1
        for (j = 0; j < theletters.getLength(); j++)
        {
          table[j + 1] = theletters.getChar(j);
        }

        table[0] = theletters.getChar(j - 1);  // don't need this

        // index in "table" of the next char to emit
        lookupIndex = (int)val / groups.getInt(count);

        // shift input by one "column"
        val = val % groups.getInt(count);

        // this should not happen
        if (lookupIndex == 0 && val == 0)
          break;

        if (lookupIndex < table.length)
        {

          // put out the next character of output       
          buf[charPos++] = table[lookupIndex];  // left to right or top to bottom                                       
        }
        else
          return XSLTErrorResources.ERROR_STRING;

        count++;
      }
    }  // end while

    // String s = new String(buf, 0, charPos);
    return new String(buf, 0, charPos);
  }

  /**
   * Convert a long integer into roman numerals.
   * @param val Value to convert.
   * @param prefixesAreOK true_ to enable prefix notation (e.g. 4 = "IV"),
   * false_ to disable prefix notation (e.g. 4 = "IIII").
   * @return Roman numeral string.
   * @see DecimalToRoman
   * @see m_romanConvertTable
   */
  protected String long2roman(long val, boolean prefixesAreOK)
  {

    if (val <= 0)
    {
      return getZeroString();
    }

    final String roman;
    int place = 0;

    if (val <= 3999L)
    {
      StringBuffer romanBuffer = new StringBuffer();
      do
      {
        while (val >= m_romanConvertTable[place].m_postValue)
        {
          romanBuffer.append(m_romanConvertTable[place].m_postLetter);
          val -= m_romanConvertTable[place].m_postValue;
        }

        if (prefixesAreOK)
        {
          if (val >= m_romanConvertTable[place].m_preValue)
          {
            romanBuffer.append(m_romanConvertTable[place].m_preLetter);
            val -= m_romanConvertTable[place].m_preValue;
          }
        }

        place++;
      }
      while (val > 0);
      roman = romanBuffer.toString();
    }
    else
    {
      roman = XSLTErrorResources.ERROR_STRING;
    }

    return roman;
  }  // end long2roman
  
  /**
   * Call the children visitors.
   * @param visitor The visitor whose appropriate method will be called.
   */
  public void callChildVisitors(XSLTVisitor visitor, boolean callAttrs)
  {
  	if(callAttrs)
  	{
	  	if(null != m_countMatchPattern)
	  		m_countMatchPattern.getExpression().callVisitors(m_countMatchPattern, visitor);
	  	if(null != m_fromMatchPattern)
	  		m_fromMatchPattern.getExpression().callVisitors(m_fromMatchPattern, visitor);
	  	if(null != m_valueExpr)
	  		m_valueExpr.getExpression().callVisitors(m_valueExpr, visitor);
	
	  	if(null != m_format_avt)
	  		m_format_avt.callVisitors(visitor);
	  	if(null != m_groupingSeparator_avt)
	  		m_groupingSeparator_avt.callVisitors(visitor);
	  	if(null != m_groupingSize_avt)
	  		m_groupingSize_avt.callVisitors(visitor);
	  	if(null != m_lang_avt)
	  		m_lang_avt.callVisitors(visitor);
	  	if(null != m_lettervalue_avt)
	  		m_lettervalue_avt.callVisitors(visitor);
  	}

    super.callChildVisitors(visitor, callAttrs);
  }


  /**
   * This class returns tokens using non-alphanumberic
   * characters as delimiters.
   */
  class NumberFormatStringTokenizer
  {

    /** Current position in the format string          */
    private int currentPosition;

    /** Index of last character in the format string      */
    private int maxPosition;

    /** Format string to be tokenized        */
    private String str;

    /**
     * Construct a NumberFormatStringTokenizer.
     *
     * @param str Format string to be tokenized
     */
    public NumberFormatStringTokenizer(String str)
    {
      this.str = str;
      maxPosition = str.length();
    }

    /**
     * Reset tokenizer so that nextToken() starts from the beginning.
     */
    public void reset()
    {
      currentPosition = 0;
    }

    /**
     * Returns the next token from this string tokenizer.
     *
     * @return     the next token from this string tokenizer.
     * @throws  NoSuchElementException  if there are no more tokens in this
     *               tokenizer's string.
     */
    public String nextToken()
    {

      if (currentPosition >= maxPosition)
      {
        throw new NoSuchElementException();
      }

      int start = currentPosition;

      while ((currentPosition < maxPosition)
             && Character.isLetterOrDigit(str.charAt(currentPosition)))
      {
        currentPosition++;
      }

      if ((start == currentPosition)
              && (!Character.isLetterOrDigit(str.charAt(currentPosition))))
      {
        currentPosition++;
      }

      return str.substring(start, currentPosition);
    }

    /**
     * Tells if there is a digit or a letter character ahead.
     *
     * @return     true if there is a number or character ahead.
     */
    public boolean isLetterOrDigitAhead()
    {

      int pos = currentPosition;

      while (pos < maxPosition)
      {
        if (Character.isLetterOrDigit(str.charAt(pos)))
          return true;

        pos++;
      }

      return false;
    }

    /**
     * Tells if there is a digit or a letter character ahead.
     *
     * @return     true if there is a number or character ahead.
     */
    public boolean nextIsSep()
    {

      if (Character.isLetterOrDigit(str.charAt(currentPosition)))
        return false;
      else
        return true;
    }

    /**
     * Tells if <code>nextToken</code> will throw an exception
     * if it is called.
     *
     * @return true if <code>nextToken</code> can be called
     * without throwing an exception.
     */
    public boolean hasMoreTokens()
    {
      return (currentPosition >= maxPosition) ? false : true;
    }

    /**
     * Calculates the number of times that this tokenizer's
     * <code>nextToken</code> method can be called before it generates an
     * exception.
     *
     * @return  the number of tokens remaining in the string using the current
     *          delimiter set.
     * @see     java.util.StringTokenizer#nextToken()
     */
    public int countTokens()
    {

      int count = 0;
      int currpos = currentPosition;

      while (currpos < maxPosition)
      {
        int start = currpos;

        while ((currpos < maxPosition)
               && Character.isLetterOrDigit(str.charAt(currpos)))
        {
          currpos++;
        }

        if ((start == currpos)
                && (Character.isLetterOrDigit(str.charAt(currpos)) == false))
        {
          currpos++;
        }

        count++;
      }

      return count;
    }
  }  // end NumberFormatStringTokenizer



}
