/*
 * 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.xsltc.runtime;

import java.text.DecimalFormat;
import java.text.FieldPosition;
import java.text.MessageFormat;
import java.text.NumberFormat;
import java.util.Locale;
import java.util.ResourceBundle;

import javax.xml.transform.dom.DOMSource;

import org.apache.xalan.xsltc.DOM;
import org.apache.xalan.xsltc.Translet;
import org.apache.xalan.xsltc.dom.AbsoluteIterator;
import org.apache.xml.dtm.Axis;
import org.apache.xalan.xsltc.dom.DOMAdapter;
import org.apache.xalan.xsltc.dom.MultiDOM;
import org.apache.xalan.xsltc.dom.SingletonIterator;
import org.apache.xalan.xsltc.dom.StepIterator;
import org.apache.xalan.xsltc.dom.ArrayNodeListIterator;
import org.apache.xml.dtm.DTM;
import org.apache.xml.dtm.DTMAxisIterator;
import org.apache.xml.dtm.DTMManager;
import org.apache.xml.dtm.ref.DTMDefaultBase;
import org.apache.xml.dtm.ref.DTMNodeProxy;

import org.w3c.dom.DOMException;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.apache.xml.serializer.NamespaceMappings;
import org.apache.xml.serializer.SerializationHandler;
import org.apache.xml.utils.XML11Char;

/**
 * Standard XSLT functions. All standard functions expect the current node 
 * and the DOM as their last two arguments.
 */
public final class BasisLibrary {

    private final static String EMPTYSTRING = "";

    /**
     * Standard function count(node-set)
     */
    public static int countF(DTMAxisIterator iterator) {
	return(iterator.getLast());
    }

    /**
     * Standard function position()
     * @deprecated This method exists only for backwards compatibility with old
     *             translets.  New code should not reference it.
     */
    public static int positionF(DTMAxisIterator iterator) {
        return iterator.isReverse()
                     ? iterator.getLast() - iterator.getPosition() + 1
                     : iterator.getPosition();
    }

    /**
     * XSLT Standard function sum(node-set). 
     * stringToDouble is inlined
     */
    public static double sumF(DTMAxisIterator iterator, DOM dom) {
	try {
	    double result = 0.0;
	    int node;
	    while ((node = iterator.next()) != DTMAxisIterator.END) {
		result += Double.parseDouble(dom.getStringValueX(node));
	    }
	    return result;
	}
	catch (NumberFormatException e) {
	    return Double.NaN;
	}
    }

    /**
     * XSLT Standard function string()
     */
    public static String stringF(int node, DOM dom) {
	return dom.getStringValueX(node);
    }

    /**
     * XSLT Standard function string(value)
     */
    public static String stringF(Object obj, DOM dom) {
	if (obj instanceof DTMAxisIterator) {
	    return dom.getStringValueX(((DTMAxisIterator)obj).reset().next());
	}
	else if (obj instanceof Node) {
	    return dom.getStringValueX(((Node)obj).node);
	}
	else if (obj instanceof DOM) {
	    return ((DOM)obj).getStringValue();
	}
	else {
	    return obj.toString();
	}
    }

    /**
     * XSLT Standard function string(value)
     */
    public static String stringF(Object obj, int node, DOM dom) {
	if (obj instanceof DTMAxisIterator) {
	    return dom.getStringValueX(((DTMAxisIterator)obj).reset().next());
	}
	else if (obj instanceof Node) {
	    return dom.getStringValueX(((Node)obj).node);
	}
	else if (obj instanceof DOM) {
	    // When the first argument is a DOM we want the whole
	    // DOM and not just a single node - that would not make sense.
	    //return ((DOM)obj).getStringValueX(node);
	    return ((DOM)obj).getStringValue();
	}
	else if (obj instanceof Double) {
	    Double d = (Double)obj;
	    final String result = d.toString();
	    final int length = result.length();
	    if ((result.charAt(length-2)=='.') &&
		(result.charAt(length-1) == '0'))
		return result.substring(0, length-2);
	    else
		return result;
	}
	else {
	    if (obj != null)
		return obj.toString();
	    else
		return stringF(node, dom);
	}
    }

    /**
     * XSLT Standard function number()
     */
    public static double numberF(int node, DOM dom) {
	return stringToReal(dom.getStringValueX(node));
    }

    /**
     * XSLT Standard function number(value)
     */
    public static double numberF(Object obj, DOM dom) {
	if (obj instanceof Double) {
	    return ((Double) obj).doubleValue();
	}
	else if (obj instanceof Integer) {
	    return ((Integer) obj).doubleValue();
	}
	else if (obj instanceof Boolean) {
	    return  ((Boolean) obj).booleanValue() ? 1.0 : 0.0;
	}
	else if (obj instanceof String) {
	    return stringToReal((String) obj);
	}
	else if (obj instanceof DTMAxisIterator) {
	    DTMAxisIterator iter = (DTMAxisIterator) obj;
	    return stringToReal(dom.getStringValueX(iter.reset().next()));
	}
	else if (obj instanceof Node) {
	    return stringToReal(dom.getStringValueX(((Node) obj).node));
	}
	else if (obj instanceof DOM) {
	    return stringToReal(((DOM) obj).getStringValue());
	}
	else {
	    final String className = obj.getClass().getName();
	    runTimeError(INVALID_ARGUMENT_ERR, className, "number()");
	    return 0.0;
	}
    }

    /**
     * XSLT Standard function round()
     */
    public static double roundF(double d) {
            return (d<-0.5 || d>0.0)?Math.floor(d+0.5):((d==0.0)?
                        d:(Double.isNaN(d)?Double.NaN:-0.0));
    }

    /**
     * XSLT Standard function boolean()
     */
    public static boolean booleanF(Object obj) {
	if (obj instanceof Double) {
	    final double temp = ((Double) obj).doubleValue();
	    return temp != 0.0 && !Double.isNaN(temp);
	}
	else if (obj instanceof Integer) {
	    return ((Integer) obj).doubleValue() != 0;
	}
	else if (obj instanceof Boolean) {
	    return  ((Boolean) obj).booleanValue();
	}
	else if (obj instanceof String) {
	    return !((String) obj).equals(EMPTYSTRING);
	}
	else if (obj instanceof DTMAxisIterator) {
	    DTMAxisIterator iter = (DTMAxisIterator) obj;
	    return iter.reset().next() != DTMAxisIterator.END;
	}
	else if (obj instanceof Node) {
	    return true;
	}
	else if (obj instanceof DOM) {
	    String temp = ((DOM) obj).getStringValue();
	    return !temp.equals(EMPTYSTRING);
	}
	else {
	    final String className = obj.getClass().getName();
	    runTimeError(INVALID_ARGUMENT_ERR, className, "boolean()");
	}
	return false;
    }

    /**
     * XSLT Standard function substring(). Must take a double because of
     * conversions resulting into NaNs and rounding.
     */
    public static String substringF(String value, double start) {
	try {
	    final int strlen = value.length();
	    int istart = (int)Math.round(start) - 1;

	    if (Double.isNaN(start)) return(EMPTYSTRING);
	    if (istart > strlen) return(EMPTYSTRING);
 	    if (istart < 1) istart = 0;

	    return value.substring(istart);
	}
	catch (IndexOutOfBoundsException e) {
	    runTimeError(RUN_TIME_INTERNAL_ERR, "substring()");
	    return null;
	}
    }

    /**
     * XSLT Standard function substring(). Must take a double because of
     * conversions resulting into NaNs and rounding.
     */
    public static String substringF(String value, double start, double length) {
	try {
	    final int strlen  = value.length();
	    int istart = (int)Math.round(start) - 1;
	    int isum   = istart + (int)Math.round(length);

	    if (Double.isInfinite(length)) isum = Integer.MAX_VALUE;

	    if (Double.isNaN(start) || Double.isNaN(length))
		return(EMPTYSTRING);
	    if (Double.isInfinite(start)) return(EMPTYSTRING);
	    if (istart > strlen) return(EMPTYSTRING);
	    if (isum < 0) return(EMPTYSTRING);
 	    if (istart < 0) istart = 0;

	    if (isum > strlen)
		return value.substring(istart);
	    else
		return value.substring(istart, isum);
	}
	catch (IndexOutOfBoundsException e) {
	    runTimeError(RUN_TIME_INTERNAL_ERR, "substring()");
	    return null;
	}
    }

    /**
     * XSLT Standard function substring-after(). 
     */
    public static String substring_afterF(String value, String substring) {
	final int index = value.indexOf(substring);
	if (index >= 0)
	    return value.substring(index + substring.length());
	else
	    return EMPTYSTRING;
    }

    /**
     * XSLT Standard function substring-before(). 
     */
    public static String substring_beforeF(String value, String substring) {
	final int index = value.indexOf(substring);
	if (index >= 0)
	    return value.substring(0, index);
	else
	    return EMPTYSTRING;
    }

    /**
     * XSLT Standard function translate(). 
     */
    public static String translateF(String value, String from, String to) {
	final int tol = to.length();
	final int froml = from.length();
	final int valuel = value.length();

	final StringBuffer result = new StringBuffer();
	for (int j, i = 0; i < valuel; i++) {
	    final char ch = value.charAt(i);
	    for (j = 0; j < froml; j++) {
		if (ch == from.charAt(j)) {
		    if (j < tol)
			result.append(to.charAt(j));
		    break;
		}
	    }	
	    if (j == froml)
		result.append(ch);
	}
	return result.toString();
    }

    /**
     * XSLT Standard function normalize-space(). 
     */
    public static String normalize_spaceF(int node, DOM dom) {
	return normalize_spaceF(dom.getStringValueX(node));
    }

    /**
     * XSLT Standard function normalize-space(string). 
     */
    public static String normalize_spaceF(String value) {
	int i = 0, n = value.length();
	StringBuffer result = new StringBuffer();

	while (i < n && isWhiteSpace(value.charAt(i)))
	    i++;

	while (true) {
	    while (i < n && !isWhiteSpace(value.charAt(i))) {
		result.append(value.charAt(i++));
	    }
	    if (i == n)
		break;
	    while (i < n && isWhiteSpace(value.charAt(i))) {
		i++;
	    }
	    if (i < n)
		result.append(' ');
	}
	return result.toString();
    }

    /**
     * XSLT Standard function generate-id(). 
     */
    public static String generate_idF(int node) {
	if (node > 0)
	    // Only generate ID if node exists
	    return "N" + node;
	else
	    // Otherwise return an empty string
	    return EMPTYSTRING;
    }
    
    /**
     * utility function for calls to local-name(). 
     */
    public static String getLocalName(String value) {
	int idx = value.lastIndexOf(':');
	if (idx >= 0) value = value.substring(idx + 1);
	idx = value.lastIndexOf('@');
	if (idx >= 0) value = value.substring(idx + 1);
	return(value);
    }

    /**
     * External functions that cannot be resolved are replaced with a call
     * to this method. This method will generate a runtime errors. A good
     * stylesheet checks whether the function exists using conditional
     * constructs, and never really tries to call it if it doesn't exist.
     * But simple stylesheets may result in a call to this method.
     * The compiler should generate a warning if it encounters a call to
     * an unresolved external function.
     */
    public static void unresolved_externalF(String name) {
	runTimeError(EXTERNAL_FUNC_ERR, name);
    }

    /**
     * Utility function to throw a runtime error on the use of an extension 
     * function when the secure processing feature is set to true.
     */
    public static void unallowed_extension_functionF(String name) {
        runTimeError(UNALLOWED_EXTENSION_FUNCTION_ERR, name);
    }

    /**
     * Utility function to throw a runtime error on the use of an extension 
     * element when the secure processing feature is set to true.
     */
    public static void unallowed_extension_elementF(String name) {
        runTimeError(UNALLOWED_EXTENSION_ELEMENT_ERR, name);
    }

    /**
     * Utility function to throw a runtime error for an unsupported element.
     * 
     * This is only used in forward-compatibility mode, when the control flow
     * cannot be determined. In 1.0 mode, the error message is emitted at 
     * compile time.
     */
    public static void unsupported_ElementF(String qname, boolean isExtension) {
	if (isExtension)
	    runTimeError(UNSUPPORTED_EXT_ERR, qname);
	else
	    runTimeError(UNSUPPORTED_XSL_ERR, qname);
    }     

    /**
     * XSLT Standard function namespace-uri(node-set).
     */
    public static String namespace_uriF(DTMAxisIterator iter, DOM dom) {
	return namespace_uriF(iter.next(), dom);
    }

    /**
     * XSLT Standard function system-property(name)
     */
    public static String system_propertyF(String name) {
	if (name.equals("xsl:version"))
	    return("1.0");
	if (name.equals("xsl:vendor"))
	    return("Apache Software Foundation (Xalan XSLTC)");
	if (name.equals("xsl:vendor-url"))
	    return("http://xml.apache.org/xalan-j");
	
	runTimeError(INVALID_ARGUMENT_ERR, name, "system-property()");
	return(EMPTYSTRING);
    }

    /**
     * XSLT Standard function namespace-uri(). 
     */
    public static String namespace_uriF(int node, DOM dom) {
	final String value = dom.getNodeName(node);
	final int colon = value.lastIndexOf(':');
	if (colon >= 0)
	    return value.substring(0, colon);
	else
	    return EMPTYSTRING;
    }

    /**
     * Implements the object-type() extension function.
     * 
     * @see <a href="http://www.exslt.org/">EXSLT</a>
     */
    public static String objectTypeF(Object obj)
    {
      if (obj instanceof String)
        return "string";
      else if (obj instanceof Boolean)
        return "boolean";
      else if (obj instanceof Number)
        return "number";
      else if (obj instanceof DOM)
        return "RTF";
      else if (obj instanceof DTMAxisIterator)
        return "node-set";
      else
        return "unknown";
    }  

    /**
     * Implements the nodeset() extension function. 
     */
    public static DTMAxisIterator nodesetF(Object obj) {
	if (obj instanceof DOM) {
	   //final DOMAdapter adapter = (DOMAdapter) obj;
	   final DOM dom = (DOM)obj;
	   return new SingletonIterator(dom.getDocument(), true);
	}
        else if (obj instanceof DTMAxisIterator) {
	   return (DTMAxisIterator) obj;
        }
        else {
	    final String className = obj.getClass().getName();
	    runTimeError(DATA_CONVERSION_ERR, "node-set", className);
	    return null;
        }
    }

    //-- Begin utility functions

    private static boolean isWhiteSpace(char ch) {
	return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r';
    }

    private static boolean compareStrings(String lstring, String rstring,
					  int op, DOM dom) {
	switch (op) {
    case Operators.EQ:
	    return lstring.equals(rstring);

    case Operators.NE:
	    return !lstring.equals(rstring);

    case Operators.GT:
	    return numberF(lstring, dom) > numberF(rstring, dom);

    case Operators.LT:
	    return numberF(lstring, dom) < numberF(rstring, dom);

    case Operators.GE:
	    return numberF(lstring, dom) >= numberF(rstring, dom);
        
    case Operators.LE:
	    return numberF(lstring, dom) <= numberF(rstring, dom);

	default:
	    runTimeError(RUN_TIME_INTERNAL_ERR, "compare()");
	    return false;
	}
    }

    /**
     * Utility function: node-set/node-set compare. 
     */
    public static boolean compare(DTMAxisIterator left, DTMAxisIterator right,
				  int op, DOM dom) {
	int lnode;
	left.reset();
	
	while ((lnode = left.next()) != DTMAxisIterator.END) {
	    final String lvalue = dom.getStringValueX(lnode);
	    
	    int rnode;
	    right.reset();
	    while ((rnode = right.next()) != DTMAxisIterator.END) {
                // String value must be the same if both nodes are the same
                if (lnode == rnode) {
                    if (op == Operators.EQ) {
                        return true;
                    } else if (op == Operators.NE) {
                        continue;
                    }
                }
		if (compareStrings(lvalue, dom.getStringValueX(rnode), op,
                                   dom)) {
		    return true;
		}
	    }
	} 
	return false;
    }

    public static boolean compare(int node, DTMAxisIterator iterator,
				  int op, DOM dom) {
	//iterator.reset();

	int rnode;
	String value;

	switch(op) {
    case Operators.EQ:
            rnode = iterator.next();
            if (rnode != DTMAxisIterator.END) {
	        value = dom.getStringValueX(node);
                do {
		    if (node == rnode
                          || value.equals(dom.getStringValueX(rnode))) {
                       return true;
                    }
	        } while ((rnode = iterator.next()) != DTMAxisIterator.END);
            }
	    break;
    case Operators.NE:
            rnode = iterator.next();
            if (rnode != DTMAxisIterator.END) {
	        value = dom.getStringValueX(node);
                do {
		    if (node != rnode
                          && !value.equals(dom.getStringValueX(rnode))) {
                        return true;
                    }
	        } while ((rnode = iterator.next()) != DTMAxisIterator.END);
            }
	    break;
    case Operators.LT:
	    // Assume we're comparing document order here
	    while ((rnode = iterator.next()) != DTMAxisIterator.END) {
		if (rnode > node) return true;
	    }
	    break;
    case Operators.GT:
	    // Assume we're comparing document order here
	    while ((rnode = iterator.next()) != DTMAxisIterator.END) {
		if (rnode < node) return true;
	    }
	    break;
	} 
	return(false);
    }

    /**
     * Utility function: node-set/number compare.
     */
    public static boolean compare(DTMAxisIterator left, final double rnumber,
				  final int op, DOM dom) {
	int node;
	//left.reset();

	switch (op) {
    case Operators.EQ:
	    while ((node = left.next()) != DTMAxisIterator.END) {
		if (numberF(dom.getStringValueX(node), dom) == rnumber)
		    return true;
	    }
	    break;

    case Operators.NE:
	    while ((node = left.next()) != DTMAxisIterator.END) {
		if (numberF(dom.getStringValueX(node), dom) != rnumber)
		    return true;
	    }
	    break;

    case Operators.GT:
	    while ((node = left.next()) != DTMAxisIterator.END) {
		if (numberF(dom.getStringValueX(node), dom) > rnumber)
		    return true;
	    }
	    break;

    case Operators.LT:
	    while ((node = left.next()) != DTMAxisIterator.END) {
		if (numberF(dom.getStringValueX(node), dom) < rnumber)
		    return true;
	    }
	    break;

    case Operators.GE:
	    while ((node = left.next()) != DTMAxisIterator.END) {
		if (numberF(dom.getStringValueX(node), dom) >= rnumber)
		    return true;
	    }
	    break;

    case Operators.LE:
	    while ((node = left.next()) != DTMAxisIterator.END) {
		if (numberF(dom.getStringValueX(node), dom) <= rnumber)
		    return true;
	    }
	    break;

	default:
	    runTimeError(RUN_TIME_INTERNAL_ERR, "compare()");
	}

	return false;
    }

    /**
     * Utility function: node-set/string comparison. 
     */
    public static boolean compare(DTMAxisIterator left, final String rstring,
				  int op, DOM dom) {
	int node;
	//left.reset();
	while ((node = left.next()) != DTMAxisIterator.END) {
	    if (compareStrings(dom.getStringValueX(node), rstring, op, dom)) {
		return true;
	    }
	}
	return false;
    }


    public static boolean compare(Object left, Object right,
				  int op, DOM dom) 
    { 
	boolean result = false;
	boolean hasSimpleArgs = hasSimpleType(left) && hasSimpleType(right);

    if (op != Operators.EQ && op != Operators.NE) {
	    // If node-boolean comparison -> convert node to boolean
	    if (left instanceof Node || right instanceof Node) {
		if (left instanceof Boolean) {
		    right = new Boolean(booleanF(right));
		    hasSimpleArgs = true;
		}
		if (right instanceof Boolean) {
		    left = new Boolean(booleanF(left));
		    hasSimpleArgs = true;
		}
	    }

	    if (hasSimpleArgs) {
		switch (op) {
        case Operators.GT:
		    return numberF(left, dom) > numberF(right, dom);
		    
        case Operators.LT:
		    return numberF(left, dom) < numberF(right, dom);
		    
        case Operators.GE:
		    return numberF(left, dom) >= numberF(right, dom);
		    
        case Operators.LE:
		    return numberF(left, dom) <= numberF(right, dom);
		    
        default:
		    runTimeError(RUN_TIME_INTERNAL_ERR, "compare()");
		}
	    }
	    // falls through
	}

	if (hasSimpleArgs) {
	    if (left instanceof Boolean || right instanceof Boolean) {
		result = booleanF(left) == booleanF(right);
	    }
	    else if (left instanceof Double || right instanceof Double ||
		     left instanceof Integer || right instanceof Integer) {
		result = numberF(left, dom) == numberF(right, dom);
	    }
	    else { // compare them as strings
		result = stringF(left, dom).equals(stringF(right, dom));
	    }

	    if (op == Operators.NE) {
		result = !result;
	    }
	}
	else {
	    if (left instanceof Node) {
		left = new SingletonIterator(((Node)left).node);
	    }
	    if (right instanceof Node) {
		right = new SingletonIterator(((Node)right).node);
	    }

	    if (hasSimpleType(left) ||
		left instanceof DOM && right instanceof DTMAxisIterator) {
		// swap operands and operator
		final Object temp = right; right = left; left = temp;
                op = Operators.swapOp(op);
	    }

	    if (left instanceof DOM) {
		if (right instanceof Boolean) {
		    result = ((Boolean)right).booleanValue();
		    return result == (op == Operators.EQ);
		}

		final String sleft = ((DOM)left).getStringValue();

		if (right instanceof Number) {
		    result = ((Number)right).doubleValue() ==
			stringToReal(sleft);
		}
		else if (right instanceof String) {
		    result = sleft.equals((String)right);
		}
		else if (right instanceof DOM) {
		    result = sleft.equals(((DOM)right).getStringValue());
		}

		if (op == Operators.NE) {
		    result = !result;
		}
		return result;
	    }

	    // Next, node-set/t for t in {real, string, node-set, result-tree}

	    DTMAxisIterator iter = ((DTMAxisIterator)left).reset();

	    if (right instanceof DTMAxisIterator) {
		result = compare(iter, (DTMAxisIterator)right, op, dom);
	    }
	    else if (right instanceof String) {
		result = compare(iter, (String)right, op, dom);
	    }	
	    else if (right instanceof Number) {
		final double temp = ((Number)right).doubleValue();
		result = compare(iter, temp, op, dom);
	    }
	    else if (right instanceof Boolean) {
		boolean temp = ((Boolean)right).booleanValue();
		result = (iter.reset().next() != DTMAxisIterator.END) == temp;
	    }
	    else if (right instanceof DOM) {
		result = compare(iter, ((DOM)right).getStringValue(),
				 op, dom);
	    }
	    else if (right == null) {
		return(false);
	    }
	    else {
		final String className = right.getClass().getName();
		runTimeError(INVALID_ARGUMENT_ERR, className, "compare()");
	    }
	}
	return result;
    }

    /**
     * Utility function: used to test context node's language
     */
    public static boolean testLanguage(String testLang, DOM dom, int node) {
	// language for context node (if any)
	String nodeLang = dom.getLanguage(node);
	if (nodeLang == null)
	    return(false);
	else
	    nodeLang = nodeLang.toLowerCase();

	// compare context node's language agains test language
	testLang = testLang.toLowerCase();
	if (testLang.length() == 2) {
	    return(nodeLang.startsWith(testLang));
	}
	else {
	    return(nodeLang.equals(testLang));
	}
    }

    private static boolean hasSimpleType(Object obj) {
	return obj instanceof Boolean || obj instanceof Double ||
	    obj instanceof Integer || obj instanceof String ||
	    obj instanceof Node || obj instanceof DOM; 
    }

    /**
     * Utility function: used in StringType to convert a string to a real.
     */
    public static double stringToReal(String s) {
	try {
	    return Double.valueOf(s).doubleValue();
	}
	catch (NumberFormatException e) {
	    return Double.NaN;
	}
    }

    /**
     * Utility function: used in StringType to convert a string to an int.
     */
    public static int stringToInt(String s) {
	try {
	    return Integer.parseInt(s);
	}
	catch (NumberFormatException e) {
	    return(-1); // ???
	}
    }

    private static final int DOUBLE_FRACTION_DIGITS = 340;
    private static final double lowerBounds = 0.001;
    private static final double upperBounds = 10000000;
    private static DecimalFormat defaultFormatter;
    private static String defaultPattern = "";

    static {
	NumberFormat f = NumberFormat.getInstance(Locale.getDefault());
	defaultFormatter = (f instanceof DecimalFormat) ?
	    (DecimalFormat) f : new DecimalFormat();
	// Set max fraction digits so that truncation does not occur. Setting 
        // the max to Integer.MAX_VALUE may cause problems with some JDK's.
	defaultFormatter.setMaximumFractionDigits(DOUBLE_FRACTION_DIGITS);
        defaultFormatter.setMinimumFractionDigits(0);
        defaultFormatter.setMinimumIntegerDigits(1);
        defaultFormatter.setGroupingUsed(false);
    }

    /**
     * Utility function: used in RealType to convert a real to a string.
     * Removes the decimal if null.
     */
    public static String realToString(double d) {
	final double m = Math.abs(d);
	if ((m >= lowerBounds) && (m < upperBounds)) {
	    final String result = Double.toString(d);
	    final int length = result.length();
	    // Remove leading zeros.
	    if ((result.charAt(length-2) == '.') &&
		(result.charAt(length-1) == '0'))
		return result.substring(0, length-2);
	    else
		return result;
	}
	else {
	    if (Double.isNaN(d) || Double.isInfinite(d))
		return(Double.toString(d));
	    return formatNumber(d, defaultPattern, defaultFormatter);
	}
    }

    /**
     * Utility function: used in RealType to convert a real to an integer
     */
    public static int realToInt(double d) {
	return (int)d;
    }

    /**
     * Utility function: used to format/adjust  a double to a string. The 
     * DecimalFormat object comes from the 'formatSymbols' hashtable in 
     * AbstractTranslet.
     */
    private static FieldPosition _fieldPosition = new FieldPosition(0);

    public static String formatNumber(double number, String pattern,
				      DecimalFormat formatter) {
        // bugzilla fix 12813 
	if (formatter == null) {
	    formatter = defaultFormatter;
	}
	try {
	    StringBuffer result = new StringBuffer();
	    if (pattern != defaultPattern) {
		formatter.applyLocalizedPattern(pattern);
	    }
            formatter.format(number, result, _fieldPosition);
	    return result.toString();
	}
	catch (IllegalArgumentException e) {
	    runTimeError(FORMAT_NUMBER_ERR, Double.toString(number), pattern);
	    return(EMPTYSTRING);
	}
    }
    
    /**
     * Utility function: used to convert references to node-sets. If the
     * obj is an instanceof Node then create a singleton iterator.
     */
    public static DTMAxisIterator referenceToNodeSet(Object obj) {
	// Convert var/param -> node
	if (obj instanceof Node) {
	    return(new SingletonIterator(((Node)obj).node));
	}
	// Convert var/param -> node-set
	else if (obj instanceof DTMAxisIterator) {
        return(((DTMAxisIterator)obj).cloneIterator().reset());
	}
	else {
	    final String className = obj.getClass().getName();
	    runTimeError(DATA_CONVERSION_ERR, className, "node-set");
	    return null;
	}
    }
    
    /**
     * Utility function: used to convert reference to org.w3c.dom.NodeList.
     */
    public static NodeList referenceToNodeList(Object obj, DOM dom) {
        if (obj instanceof Node || obj instanceof DTMAxisIterator) {
            DTMAxisIterator iter = referenceToNodeSet(obj);
            return dom.makeNodeList(iter);
        }
        else if (obj instanceof DOM) {
          dom = (DOM)obj;
          return dom.makeNodeList(DTMDefaultBase.ROOTNODE);
        }
	else {
	    final String className = obj.getClass().getName();
	    runTimeError(DATA_CONVERSION_ERR, className, 
                "org.w3c.dom.NodeList");
	    return null;
	}
    }

    /**
     * Utility function: used to convert reference to org.w3c.dom.Node.
     */
    public static org.w3c.dom.Node referenceToNode(Object obj, DOM dom) {
        if (obj instanceof Node || obj instanceof DTMAxisIterator) {
            DTMAxisIterator iter = referenceToNodeSet(obj);
            return dom.makeNode(iter);
        }
        else if (obj instanceof DOM) {
          dom = (DOM)obj;
          DTMAxisIterator iter = dom.getChildren(DTMDefaultBase.ROOTNODE);
          return dom.makeNode(iter);
        }
	else {
	    final String className = obj.getClass().getName();
	    runTimeError(DATA_CONVERSION_ERR, className, "org.w3c.dom.Node");
	    return null;
	}
    }
   
    /**
     * Utility function: used to convert reference to long.
     */
    public static long referenceToLong(Object obj) {
        if (obj instanceof Number) {
            return ((Number) obj).longValue();    // handles Integer and Double
        }
        else {
	    final String className = obj.getClass().getName();
	    runTimeError(DATA_CONVERSION_ERR, className, Long.TYPE);
	    return 0;
        }
    }
            
    /**
     * Utility function: used to convert reference to double.
     */
    public static double referenceToDouble(Object obj) {
        if (obj instanceof Number) {
            return ((Number) obj).doubleValue();   // handles Integer and Double
        }
        else {
	    final String className = obj.getClass().getName();
	    runTimeError(DATA_CONVERSION_ERR, className, Double.TYPE);
	    return 0;
        }
    }

    /**
     * Utility function: used to convert reference to boolean.
     */
    public static boolean referenceToBoolean(Object obj) {
        if (obj instanceof Boolean) {
            return ((Boolean) obj).booleanValue();
        }
        else {
	    final String className = obj.getClass().getName();
	    runTimeError(DATA_CONVERSION_ERR, className, Boolean.TYPE);
	    return false;
        }
    }

    /**
     * Utility function: used to convert reference to String.
     */
    public static String referenceToString(Object obj, DOM dom) {
        if (obj instanceof String) {
            return (String) obj;
        }
        else if (obj instanceof DTMAxisIterator) {
	    return dom.getStringValueX(((DTMAxisIterator)obj).reset().next());
	}
	else if (obj instanceof Node) {
	    return dom.getStringValueX(((Node)obj).node);
	}
	else if (obj instanceof DOM) {
	    return ((DOM) obj).getStringValue();
	}
        else {
	    final String className = obj.getClass().getName();
	    runTimeError(DATA_CONVERSION_ERR, className, String.class);
	    return null;
        }
    }

    /**
     * Utility function used to convert a w3c Node into an internal DOM iterator. 
     */
    public static DTMAxisIterator node2Iterator(org.w3c.dom.Node node,
	Translet translet, DOM dom) 
    {
        final org.w3c.dom.Node inNode = node;
        // Create a dummy NodeList which only contains the given node to make 
        // use of the nodeList2Iterator() interface.
        org.w3c.dom.NodeList nodelist = new org.w3c.dom.NodeList() {            
            public int getLength() {
                return 1;
            }
            
            public org.w3c.dom.Node item(int index) {
                if (index == 0)
                    return inNode;
                else
                    return null;
            }
        };
        
        return nodeList2Iterator(nodelist, translet, dom);
    }
    
    /**
     * In a perfect world, this would be the implementation for
     * nodeList2Iterator. In reality, though, this causes a
     * ClassCastException in getDTMHandleFromNode because SAXImpl is
     * not an instance of DOM2DTM. So we use the more lengthy
     * implementation below until this issue has been addressed.
     *
     * @see org.apache.xml.dtm.ref.DTMManagerDefault#getDTMHandleFromNode
     */
    private static DTMAxisIterator nodeList2IteratorUsingHandleFromNode(
                                        org.w3c.dom.NodeList nodeList,
                                    	Translet translet, DOM dom)
    {
	final int n = nodeList.getLength();
	final int[] dtmHandles = new int[n];
	DTMManager dtmManager = null;
	if (dom instanceof MultiDOM)
	    dtmManager = ((MultiDOM) dom).getDTMManager();
	for (int i = 0; i < n; ++i) {
	    org.w3c.dom.Node node = nodeList.item(i);
	    int handle;
	    if (dtmManager != null) {
		handle = dtmManager.getDTMHandleFromNode(node);
	    }
	    else if (node instanceof DTMNodeProxy
		     && ((DTMNodeProxy) node).getDTM() == dom) {
		handle = ((DTMNodeProxy) node).getDTMNodeNumber();
	    }
	    else {
		runTimeError(RUN_TIME_INTERNAL_ERR, "need MultiDOM");
		return null;
	    }
	    dtmHandles[i] = handle;
	    System.out.println("Node " + i + " has handle 0x" +
			       Integer.toString(handle, 16));
	}
	return new ArrayNodeListIterator(dtmHandles);
    }

    /**
     * Utility function used to convert a w3c NodeList into a internal
     * DOM iterator. 
     */
    public static DTMAxisIterator nodeList2Iterator(
                                        org.w3c.dom.NodeList nodeList,
                                    	Translet translet, DOM dom) 
    {
	// First pass: build w3c DOM for all nodes not proxied from our DOM.
	//
	// Notice: this looses some (esp. parent) context for these nodes,
	// so some way to wrap the original nodes inside a DTMAxisIterator
	// might be preferable in the long run.
	int n = 0; // allow for change in list length, just in case.
	Document doc = null;
	DTMManager dtmManager = null;
	int[] proxyNodes = new int[nodeList.getLength()];
	if (dom instanceof MultiDOM)
	    dtmManager = ((MultiDOM) dom).getDTMManager();
	for (int i = 0; i < nodeList.getLength(); ++i) {
	    org.w3c.dom.Node node = nodeList.item(i);
	    if (node instanceof DTMNodeProxy) {
		DTMNodeProxy proxy = (DTMNodeProxy)node;
		DTM nodeDTM = proxy.getDTM();
		int handle = proxy.getDTMNodeNumber();
		boolean isOurDOM = (nodeDTM == dom);
		if (!isOurDOM && dtmManager != null) {
		    try {
			isOurDOM = (nodeDTM == dtmManager.getDTM(handle));
		    }
		    catch (ArrayIndexOutOfBoundsException e) {
			// invalid node handle, so definitely not our doc
		    }
		}
		if (isOurDOM) {
		    proxyNodes[i] = handle;
		    ++n;
		    continue;
		}
	    }
	    proxyNodes[i] = DTM.NULL;
	    int nodeType = node.getNodeType();
	    if (doc == null) {
		if (dom instanceof MultiDOM == false) {
		    runTimeError(RUN_TIME_INTERNAL_ERR, "need MultiDOM");
		    return null;
		}
		try {
		    AbstractTranslet at = (AbstractTranslet) translet;
		    doc = at.newDocument("", "__top__");
		}
		catch (javax.xml.parsers.ParserConfigurationException e) {
		    runTimeError(RUN_TIME_INTERNAL_ERR, e.getMessage());
		    return null;
		}
	    }
	    // Use one dummy element as container for each node of the
	    // list. That way, it is easier to detect resp. avoid
	    // funny things which change the number of nodes,
	    // e.g. auto-concatenation of text nodes.
	    Element mid;
	    switch (nodeType) {
		case org.w3c.dom.Node.ELEMENT_NODE:
		case org.w3c.dom.Node.TEXT_NODE:
		case org.w3c.dom.Node.CDATA_SECTION_NODE:
		case org.w3c.dom.Node.COMMENT_NODE:
		case org.w3c.dom.Node.ENTITY_REFERENCE_NODE:
		case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
		    mid = doc.createElementNS(null, "__dummy__");
		    mid.appendChild(doc.importNode(node, true));
		    doc.getDocumentElement().appendChild(mid);
		    ++n;
		    break;
		case org.w3c.dom.Node.ATTRIBUTE_NODE:
		    // The mid element also serves as a container for
		    // attributes, avoiding problems with conflicting
		    // attributes or node order.
		    mid = doc.createElementNS(null, "__dummy__");
		    mid.setAttributeNodeNS((Attr)doc.importNode(node, true));
		    doc.getDocumentElement().appendChild(mid);
		    ++n;
		    break;
		default:
		    // Better play it safe for all types we aren't sure we know
		    // how to deal with.
		    runTimeError(RUN_TIME_INTERNAL_ERR,
				 "Don't know how to convert node type "
				 + nodeType);
	    }
	}

        // w3cDOM -> DTM -> DOMImpl
	DTMAxisIterator iter = null, childIter = null, attrIter = null;
	if (doc != null) {
	    final MultiDOM multiDOM = (MultiDOM) dom;
	    DOM idom = (DOM)dtmManager.getDTM(new DOMSource(doc), false,
					      null, true, false);
	    // Create DOMAdapter and register with MultiDOM
	    DOMAdapter domAdapter = new DOMAdapter(idom, 
                translet.getNamesArray(),
                translet.getUrisArray(),
                translet.getTypesArray(),
		translet.getNamespaceArray());
            multiDOM.addDOMAdapter(domAdapter);

	    DTMAxisIterator iter1 = idom.getAxisIterator(Axis.CHILD);
	    DTMAxisIterator iter2 = idom.getAxisIterator(Axis.CHILD);
            iter = new AbsoluteIterator(
                new StepIterator(iter1, iter2));

 	    iter.setStartNode(DTMDefaultBase.ROOTNODE);

	    childIter = idom.getAxisIterator(Axis.CHILD);
	    attrIter = idom.getAxisIterator(Axis.ATTRIBUTE);
	}

	// Second pass: find DTM handles for every node in the list.
	int[] dtmHandles = new int[n];
	n = 0;
	for (int i = 0; i < nodeList.getLength(); ++i) {
	    if (proxyNodes[i] != DTM.NULL) {
		dtmHandles[n++] = proxyNodes[i];
		continue;
	    }
	    org.w3c.dom.Node node = nodeList.item(i);
	    DTMAxisIterator iter3 = null;
	    int nodeType = node.getNodeType();
	    switch (nodeType) {
		case org.w3c.dom.Node.ELEMENT_NODE:
		case org.w3c.dom.Node.TEXT_NODE:
		case org.w3c.dom.Node.CDATA_SECTION_NODE:
		case org.w3c.dom.Node.COMMENT_NODE:
		case org.w3c.dom.Node.ENTITY_REFERENCE_NODE:
		case org.w3c.dom.Node.PROCESSING_INSTRUCTION_NODE:
		    iter3 = childIter;
		    break;
		case org.w3c.dom.Node.ATTRIBUTE_NODE:
		    iter3 = attrIter;
		    break;
		default:
		    // Should not happen, as first run should have got all these
		    throw new InternalRuntimeError("Mismatched cases");
	    }
	    if (iter3 != null) {
		iter3.setStartNode(iter.next());
		dtmHandles[n] = iter3.next();
		// For now, play it self and perform extra checks:
		if (dtmHandles[n] == DTMAxisIterator.END)
		    throw new InternalRuntimeError("Expected element missing at " + i);
		if (iter3.next() != DTMAxisIterator.END)
		    throw new InternalRuntimeError("Too many elements at " + i);
		++n;
	    }
	}
	if (n != dtmHandles.length)
	    throw new InternalRuntimeError("Nodes lost in second pass");

	return new ArrayNodeListIterator(dtmHandles);
    }

    /**
     * Utility function used to convert references to DOMs. 
     */
    public static DOM referenceToResultTree(Object obj) {
	try {
	    return ((DOM) obj);
	}
	catch (IllegalArgumentException e) {
	    final String className = obj.getClass().getName();
	    runTimeError(DATA_CONVERSION_ERR, "reference", className);
	    return null;
	}
    }

    /**
     * Utility function: used with nth position filters to convert a sequence
     * of nodes to just one single node (the one at position n).
     */
    public static DTMAxisIterator getSingleNode(DTMAxisIterator iterator) {
	int node = iterator.next();
	return(new SingletonIterator(node));
    }

    /**
     * Utility function: used in xsl:copy.
     */
    private static char[] _characterArray = new char[32];

    public static void copy(Object obj,
 			    SerializationHandler handler,
			    int node,
			    DOM dom) {
	try {
	    if (obj instanceof DTMAxisIterator) 
      {
		DTMAxisIterator iter = (DTMAxisIterator) obj;
		dom.copy(iter.reset(), handler);
	    }
	    else if (obj instanceof Node) {
		dom.copy(((Node) obj).node, handler);
	    }
	    else if (obj instanceof DOM) {
		//((DOM)obj).copy(((org.apache.xml.dtm.ref.DTMDefaultBase)((DOMAdapter)obj).getDOMImpl()).getDocument(), handler);
		DOM newDom = (DOM)obj;
		newDom.copy(newDom.getDocument(), handler);
	    }
	    else {
		String string = obj.toString();		// or call stringF()
		final int length = string.length();
		if (length > _characterArray.length)
		    _characterArray = new char[length];
		string.getChars(0, length, _characterArray, 0);
		handler.characters(_characterArray, 0, length);
	    }
	}
	catch (SAXException e) {
	    runTimeError(RUN_TIME_COPY_ERR);
	}
    }
    
    /**
     * Utility function to check if xsl:attribute has a valid qname
     * This method should only be invoked if the name attribute is an AVT
     */    
    public static void checkAttribQName(String name) {
        final int firstOccur = name.indexOf(":");
        final int lastOccur = name.lastIndexOf(":");
        final String localName = name.substring(lastOccur + 1);
        
        if (firstOccur > 0) {
            final String newPrefix = name.substring(0, firstOccur); 
        
            if (firstOccur != lastOccur) {
               final String oriPrefix = name.substring(firstOccur+1, lastOccur); 
                if (!XML11Char.isXML11ValidNCName(oriPrefix)) {
                    // even though the orignal prefix is ignored, it should still get checked for valid NCName
                    runTimeError(INVALID_QNAME_ERR,oriPrefix+":"+localName);
                }
            }
            
            // prefix must be a valid NCName
            if (!XML11Char.isXML11ValidNCName(newPrefix)) {
                runTimeError(INVALID_QNAME_ERR,newPrefix+":"+localName); 
            }  
        }
                
        // local name must be a valid NCName and must not be XMLNS
        if ((!XML11Char.isXML11ValidNCName(localName))||(localName.equals(Constants.XMLNS_PREFIX))) {
            runTimeError(INVALID_QNAME_ERR,localName); 
        }
    }
    
    /**
     * Utility function to check if a name is a valid ncname
     * This method should only be invoked if the attribute value is an AVT
     */    
    public static void checkNCName(String name) {
        if (!XML11Char.isXML11ValidNCName(name)) {
            runTimeError(INVALID_NCNAME_ERR,name); 
        }  
    }        

    /**
     * Utility function to check if a name is a valid qname
     * This method should only be invoked if the attribute value is an AVT
     */    
    public static void checkQName(String name) {
        if (!XML11Char.isXML11ValidQName(name)) {
            runTimeError(INVALID_QNAME_ERR,name); 
        }  
    }
    
    /**
     * Utility function for the implementation of xsl:element.
     */
    public static String startXslElement(String qname, String namespace,
	SerializationHandler handler, DOM dom, int node)
    {
        try {
            // Get prefix from qname
            String prefix;
            final int index = qname.indexOf(':');
            
            if (index > 0) {
                prefix = qname.substring(0, index);
                
                // Handle case when prefix is not known at compile time
                if (namespace == null || namespace.length() == 0) {
                    runTimeError(NAMESPACE_PREFIX_ERR,prefix);
                }
                
                handler.startElement(namespace, qname.substring(index+1),
                                         qname);
                handler.namespaceAfterStartElement(prefix, namespace); 
            }
            else {                      
                // Need to generate a prefix?
                if (namespace != null && namespace.length() > 0) {
                    prefix = generatePrefix();
                    qname = prefix + ':' + qname;   
                    handler.startElement(namespace, qname, qname);   
                    handler.namespaceAfterStartElement(prefix, namespace);
                }
                else {
                    handler.startElement(null, null, qname);   
                }
            }
        }
        catch (SAXException e) {
            throw new RuntimeException(e.getMessage());
        }
    
        return qname;
    }    
 
    /**
     * <p>Look up the namespace for a lexical QName using the namespace
     * declarations available at a particular location in the stylesheet.</p>
     * <p>See {@link org.apache.xalan.xsltc.compiler.Stylesheet#compileStaticInitializer(org.apache.xalan.xsltc.compiler.util.ClassGenerator)}
     * for more information about the <code>ancestorNodeIDs</code>,
     * <code>prefixURIsIndex</code> and <code>prefixURIPairs</code arrays.</p>
     *
     * @param lexicalQName The QName as a <code>java.lang.String</code>
     * @param stylesheetNodeID An <code>int</code> representing the element in
     *                     the stylesheet relative to which the namespace of
     *                     the lexical QName is to be determined
     * @param ancestorNodeIDs An <code>int</code> array, indexed by stylesheet
     *                     node IDs, containing the ID of the nearest ancestor
     *                     node in the stylesheet that has namespace
     *                     declarations, or <code>-1</code> if there is no
     *                     such ancestor
     * @param prefixURIsIndex An <code>int</code> array, indexed by stylesheet
     *                     node IDs, containing the index into the
     *                     <code>prefixURIPairs</code> array of the first
     *                     prefix declared on that stylesheet node
     * @param prefixURIPairs A <code>java.lang.String</code> array that contains
     *                     pairs of 
     * @param ignoreDefault A <code>boolean</code> indicating whether any
     *                     default namespace decarlation should be considered
     * @return The namespace of the lexical QName or a zero-length string if
     *         the QName is in no namespace or no namespace declaration for the
     *         prefix of the QName was found
     */
    public static String lookupStylesheetQNameNamespace(String lexicalQName,
                                                        int stylesheetNodeID,
                                                        int[] ancestorNodeIDs,
                                                        int[] prefixURIsIndex,
                                                        String[] prefixURIPairs,
                                                        boolean ignoreDefault) {
        String prefix = getPrefix(lexicalQName);
        String uri = "";

        if (prefix == null && !ignoreDefault) {
            prefix = "";
        }

        if (prefix != null) {
            // Loop from current node in the stylesheet to its ancestors
            nodeLoop:
            for (int currentNodeID = stylesheetNodeID;
                 currentNodeID >= 0;
                 currentNodeID = ancestorNodeIDs[currentNodeID]) {
                // Look at all declarations on the current stylesheet node
                // The prefixURIsIndex is an array of indices into the
                // prefixURIPairs array that are stored in ascending order.
                // The declarations for a node I are in elements
                // prefixURIsIndex[I] to prefixURIsIndex[I+1]-1 (or 
                // prefixURIPairs.length-1 if I is the last node)
                int prefixStartIdx = prefixURIsIndex[currentNodeID];
                int prefixLimitIdx = (currentNodeID+1 < prefixURIsIndex.length)
                                         ? prefixURIsIndex[currentNodeID + 1]
                                         : prefixURIPairs.length;

                for (int prefixIdx = prefixStartIdx;
                     prefixIdx < prefixLimitIdx;
                     prefixIdx = prefixIdx + 2) {
                    // Did we find the declaration of our prefix
                    if (prefix.equals(prefixURIPairs[prefixIdx])) {
                        uri = prefixURIPairs[prefixIdx+1];
                        break nodeLoop;
                    }
                }
            }
        }

        return uri;
    }

    /**
     * <p>Look up the namespace for a lexical QName using the namespace
     * declarations available at a particular location in the stylesheet and
     * return the expanded QName</p>
     * <p>See {@link org.apache.xalan.xsltc.compiler.Stylesheet#compileStaticInitializer(org.apache.xalan.xsltc.compiler.util.ClassGenerator)}
     * for more information about the <code>ancestorNodeIDs</code>,
     * <code>prefixURIsIndex</code> and <code>prefixURIPairs</code arrays.</p>
     *
     * @param lexicalQName The QName as a <code>java.lang.String</code>
     * @param stylesheetNodeID An <code>int</code> representing the element in
     *                     the stylesheet relative to which the namespace of
     *                     the lexical QName is to be determined
     * @param ancestorNodeIDs An <code>int</code> array, indexed by stylesheet
     *                     node IDs, containing the ID of the nearest ancestor
     *                     node in the stylesheet that has namespace
     *                     declarations, or <code>-1</code> if there is no
     *                     such ancestor
     * @param prefixURIsIndex An <code>int</code> array, indexed by stylesheet
     *                     node IDs, containing the index into the
     *                     <code>prefixURIPairs</code> array of the first
     *                     prefix declared on that stylesheet node
     * @param prefixURIPairs A <code>java.lang.String</code> array that contains
     *                     pairs of
     * @param ignoreDefault A <code>boolean</code> indicating whether any
     *                     default namespace decarlation should be considered
     * @return The expanded QName in the form "uri:localName" or just
     *         "localName" if the QName is in no namespace or no namespace
     *         declaration for the prefix of the QName was found
     */
    public static String expandStylesheetQNameRef(String lexicalQName,
                                                  int stylesheetNodeID,
                                                  int[] ancestorNodeIDs,
                                                  int[] prefixURIsIndex,
                                                  String[] prefixURIPairs,
                                                  boolean ignoreDefault) {
        String expandedQName;
        String prefix = getPrefix(lexicalQName);
        String localName = (prefix != null)
                               ? lexicalQName.substring(prefix.length()+1)
                               : lexicalQName;
        String uri = lookupStylesheetQNameNamespace(lexicalQName,
                                                    stylesheetNodeID,
                                                    ancestorNodeIDs,
                                                    prefixURIsIndex,
                                                    prefixURIPairs,
                                                    ignoreDefault);

        // Handle case when prefix is not resolved
        if (prefix != null && prefix.length() != 0
               && (uri == null || uri.length() == 0)) {
            runTimeError(NAMESPACE_PREFIX_ERR, prefix);
        }

        if (uri.length() == 0) {
            expandedQName = localName;
        } else {
            expandedQName = uri + ':' + localName;
        }

        return expandedQName;
    }

    /**
     * This function is used in the execution of xsl:element
     */
    public static String getPrefix(String qname) {
	final int index = qname.indexOf(':');
	return (index > 0) ? qname.substring(0, index) : null;
    }

    /**
     * This function is used in the execution of xsl:element
     */
    private static int prefixIndex = 0;		// not thread safe!!
    public static String generatePrefix() {
	return ("ns" + prefixIndex++);
    }

    public static final String RUN_TIME_INTERNAL_ERR =
                                           "RUN_TIME_INTERNAL_ERR";
    public static final String RUN_TIME_COPY_ERR =
                                           "RUN_TIME_COPY_ERR";
    public static final String DATA_CONVERSION_ERR =
                                           "DATA_CONVERSION_ERR";
    public static final String EXTERNAL_FUNC_ERR =
                                           "EXTERNAL_FUNC_ERR";
    public static final String EQUALITY_EXPR_ERR =
                                           "EQUALITY_EXPR_ERR";
    public static final String INVALID_ARGUMENT_ERR =
                                           "INVALID_ARGUMENT_ERR";
    public static final String FORMAT_NUMBER_ERR =
                                           "FORMAT_NUMBER_ERR";
    public static final String ITERATOR_CLONE_ERR =
                                           "ITERATOR_CLONE_ERR";
    public static final String AXIS_SUPPORT_ERR =
                                           "AXIS_SUPPORT_ERR";
    public static final String TYPED_AXIS_SUPPORT_ERR =
                                           "TYPED_AXIS_SUPPORT_ERR";
    public static final String STRAY_ATTRIBUTE_ERR =
                                           "STRAY_ATTRIBUTE_ERR"; 
    public static final String STRAY_NAMESPACE_ERR =
                                           "STRAY_NAMESPACE_ERR";
    public static final String NAMESPACE_PREFIX_ERR =
                                           "NAMESPACE_PREFIX_ERR";
    public static final String DOM_ADAPTER_INIT_ERR =
                                           "DOM_ADAPTER_INIT_ERR";
    public static final String PARSER_DTD_SUPPORT_ERR =
                                           "PARSER_DTD_SUPPORT_ERR";
    public static final String NAMESPACES_SUPPORT_ERR =
                                           "NAMESPACES_SUPPORT_ERR";
    public static final String CANT_RESOLVE_RELATIVE_URI_ERR =
                                           "CANT_RESOLVE_RELATIVE_URI_ERR";
    public static final String UNSUPPORTED_XSL_ERR =
                                           "UNSUPPORTED_XSL_ERR";
    public static final String UNSUPPORTED_EXT_ERR =
                                           "UNSUPPORTED_EXT_ERR";
    public static final String UNKNOWN_TRANSLET_VERSION_ERR =
                                           "UNKNOWN_TRANSLET_VERSION_ERR";
    public static final String INVALID_QNAME_ERR = "INVALID_QNAME_ERR";                                           
    public static final String INVALID_NCNAME_ERR = "INVALID_NCNAME_ERR";
    public static final String UNALLOWED_EXTENSION_FUNCTION_ERR = "UNALLOWED_EXTENSION_FUNCTION_ERR";
    public static final String UNALLOWED_EXTENSION_ELEMENT_ERR = "UNALLOWED_EXTENSION_ELEMENT_ERR";

    // All error messages are localized and are stored in resource bundles.
    private static ResourceBundle m_bundle;
    
    public final static String ERROR_MESSAGES_KEY = "error-messages";

    static {
	String resource = "org.apache.xalan.xsltc.runtime.ErrorMessages";
	m_bundle = ResourceBundle.getBundle(resource);
    }

    /**
     * Print a run-time error message.
     */
    public static void runTimeError(String code) {
	throw new RuntimeException(m_bundle.getString(code));
    }

    public static void runTimeError(String code, Object[] args) {
	final String message = MessageFormat.format(m_bundle.getString(code),
                                                    args);
	throw new RuntimeException(message);
    }

    public static void runTimeError(String code, Object arg0) {
	runTimeError(code, new Object[]{ arg0 } );
    }

    public static void runTimeError(String code, Object arg0, Object arg1) {
	runTimeError(code, new Object[]{ arg0, arg1 } );
    }

    public static void consoleOutput(String msg) {
	System.out.println(msg);
    }

    /**
     * Replace a certain character in a string with a new substring.
     */
    public static String replace(String base, char ch, String str) {
	return (base.indexOf(ch) < 0) ? base : 
	    replace(base, String.valueOf(ch), new String[] { str });
    }

    public static String replace(String base, String delim, String[] str) {
	final int len = base.length();
	final StringBuffer result = new StringBuffer();

	for (int i = 0; i < len; i++) {
	    final char ch = base.charAt(i);
	    final int k = delim.indexOf(ch);

	    if (k >= 0) {
		result.append(str[k]);
	    }
	    else {
		result.append(ch);
	    }
	}
	return result.toString();
    }


    /**
     * Utility method to allow setting parameters of the form
     * {namespaceuri}localName
     * which get mapped to an instance variable in the class
     * Hence  a parameter of the form "{http://foo.bar}xyz"
     * will be replaced with the corresponding values  
     * by the BasisLibrary's utility method mapQNametoJavaName
     * and thus get mapped to legal java variable names 
     */
    public static String mapQNameToJavaName (String base ) {
       return replace(base, ".-:/{}?#%*",
                      new String[] { "$dot$", "$dash$" ,"$colon$", "$slash$",
                                     "","$colon$","$ques$","$hash$","$per$",
                                     "$aster$"});

    }

    //-- End utility functions
}
