/*******************************************************************************
 * Copyright (c) 2008 Standards for Technology in Automotive Retail
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     David Carver - STAR - bug 224197 - initial API and implementation
 *                    based on work from Apache Xalan 2.7.0
 *******************************************************************************/
/*
 * Copyright 1999-2004 The Apache Software Foundation.
 *
 * Licensed 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: StylesheetRoot.java,v 1.4 2008/03/28 02:38:15 dacarver Exp $
 */
package org.eclipse.wst.xsl.core.internal.compiler.xslt10.templates;

import java.text.DecimalFormatSymbols;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Vector;

import javax.xml.transform.ErrorListener;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;

import org.eclipse.wst.xsl.core.compiler.xslt10.res.XSLTErrorResources;
import org.eclipse.wst.xsl.core.internal.compiler.xslt10.extensions.ExtensionNamespacesManager;
import org.eclipse.wst.xsl.core.internal.compiler.xslt10.processor.XSLTSchema;
import org.eclipse.wst.xsl.core.compiler.xslt10.res.Messages;

import org.eclipse.wst.xsl.core.internal.compiler.xslt10.transformer.TransformerImpl;
import org.apache.xml.dtm.DTM;
import org.apache.xml.dtm.ref.ExpandedNameTable;
import org.apache.xml.utils.IntStack;
import org.apache.xml.utils.QName;
import org.eclipse.wst.xsl.core.internal.compiler.xslt10.xpath.XPath;
import org.apache.xpath.XPathContext;

/**
 * This class represents the root object of the stylesheet tree.
 * 
 * @xsl.usage general
 */
public class StylesheetRoot extends StylesheetComposed implements
		java.io.Serializable, Templates {
	static final long serialVersionUID = 3875353123529147855L;

	/**
	 * The flag for the setting of the optimize feature;
	 */
	private boolean m_optimizer = true;

	/**
	 * The flag for the setting of the incremental feature;
	 */
	private boolean m_incremental = false;

	/**
	 * The flag for the setting of the source_location feature;
	 */
	private boolean m_source_location = false;

	/**
	 * State of the secure processing feature.
	 */
	private boolean m_isSecureProcessing = false;

	private ErrorListener m_errorListener = null;

	/**
	 * Uses an XSL stylesheet document.
	 * 
	 * @throws TransformerConfigurationException
	 *             if the baseIdentifier can not be resolved to a URL.
	 */
	public StylesheetRoot(ErrorListener errorListener)
			throws TransformerConfigurationException {

		super(null);

		setStylesheetRoot(this);
		m_errorListener = errorListener;

		try {
			m_selectDefault = new XPath("node()", this, this, XPath.SELECT,
					errorListener);

			initDefaultRule(errorListener);
		} catch (TransformerException se) {
			throw new TransformerConfigurationException(Messages.createMessage(
					XSLTErrorResources.ER_CANNOT_INIT_DEFAULT_TEMPLATES, null),
					se); // "Can't init default templates!", se);
		}
	}

	/**
	 * The schema used when creating this StylesheetRoot
	 * 
	 * @serial
	 */
	private Hashtable m_availElems;

	/**
	 * Creates a StylesheetRoot and retains a pointer to the schema used to
	 * create this StylesheetRoot. The schema may be needed later for an
	 * element-available() function call.
	 * 
	 * @param schema
	 *            The schema used to create this stylesheet
	 * @throws TransformerConfigurationException
	 *             if the baseIdentifier can not be resolved to a URL.
	 */
	public StylesheetRoot(XSLTSchema schema, ErrorListener listener)
			throws TransformerConfigurationException {

		this(listener);
		m_availElems = schema.getElemsAvailable();
	}

	/**
	 * Tell if this is the root of the stylesheet tree.
	 * 
	 * @return True since this is the root of the stylesheet tree.
	 */
	@Override
	public boolean isRoot() {
		return true;
	}

	/**
	 * Set the state of the secure processing feature.
	 */
	public void setSecureProcessing(boolean flag) {
		m_isSecureProcessing = flag;
	}

	/**
	 * Return the state of the secure processing feature.
	 */
	public boolean isSecureProcessing() {
		return m_isSecureProcessing;
	}

	/**
	 * Get the hashtable of available elements.
	 * 
	 * @return table of available elements, keyed by qualified names, and with
	 *         values of the same qualified names.
	 */
	public Hashtable getAvailableElements() {
		return m_availElems;
	}

	private transient ExtensionNamespacesManager m_extNsMgr = null;

	/**
	 * Only instantiate an ExtensionNamespacesManager if one is called for
	 * (i.e., if the stylesheet contains extension functions and/or elements).
	 */
	public ExtensionNamespacesManager getExtensionNamespacesManager() {
		if (m_extNsMgr == null)
			m_extNsMgr = new ExtensionNamespacesManager();
		return m_extNsMgr;
	}

	/**
	 * Get the vector of extension namespaces. Used to provide the extensions
	 * table access to a list of extension namespaces encountered during
	 * composition of a stylesheet.
	 */
	public Vector getExtensions() {
		return m_extNsMgr != null ? m_extNsMgr.getExtensions() : null;
	}

	/*
	 * public void runtimeInit(TransformerImpl transformer) throws
	 * TransformerException {
	 * System.out.println("StylesheetRoot.runtimeInit()");
	 *  // try{throw new Exception("StylesheetRoot.runtimeInit()");}
	 * catch(Exception e){e.printStackTrace();}
	 *  }
	 */

	// ============== Templates Interface ================
	/**
	 * Create a new transformation context for this Templates object.
	 * 
	 * @return A Transformer instance, never null.
	 */
	public Transformer newTransformer() {
		return new TransformerImpl(this);
	}

	public Properties getDefaultOutputProps() {
		return m_outputProperties.getProperties();
	}

	/**
	 * Get the static properties for xsl:output. The object returned will be a
	 * clone of the internal values, and thus it can be mutated without mutating
	 * the Templates object, and then handed in to the process method.
	 * 
	 * <p>
	 * For XSLT, Attribute Value Templates attribute values will be returned
	 * unexpanded (since there is no context at this point).
	 * </p>
	 * 
	 * @return A Properties object, not null.
	 */
	public Properties getOutputProperties() {
		return (Properties) getDefaultOutputProps().clone();
	}

	// ============== End Templates Interface ================

	/**
	 * Recompose the values of all "composed" properties, meaning properties
	 * that need to be combined or calculated from the combination of imported
	 * and included stylesheets. This method determines the proper import
	 * precedence of all imported stylesheets. It then iterates through all of
	 * the elements and properties in the proper order and triggers the
	 * individual recompose methods.
	 * 
	 * @throws TransformerException
	 */
	public void recompose() throws TransformerException {
		// Now we make a Vector that is going to hold all of the recomposable
		// elements

		Vector recomposableElements = new Vector();

		// First, we build the global import tree.

		if (null == m_globalImportList) {

			Vector importList = new Vector();

			addImports(this, true, importList);

			// Now we create an array and reverse the order of the importList
			// vector.
			// We built the importList vector backwards so that we could use
			// addElement
			// to append to the end of the vector instead of constantly pushing
			// new
			// stylesheets onto the front of the vector and having to shift the
			// rest
			// of the vector each time.

			m_globalImportList = new StylesheetComposed[importList.size()];

			for (int i = 0, j = importList.size() - 1; i < importList.size(); i++) {
				m_globalImportList[j] = (StylesheetComposed) importList
						.elementAt(i);
				// Build the global include list for this stylesheet.
				// This needs to be done ahead of the recomposeImports
				// because we need the info from the composed includes.
				m_globalImportList[j].recomposeIncludes(m_globalImportList[j]);
				// Calculate the number of this import.
				m_globalImportList[j--].recomposeImports();
			}
		}
		// Next, we walk the import tree and add all of the recomposable
		// elements to the vector.
		int n = getGlobalImportCount();

		for (int i = 0; i < n; i++) {
			StylesheetComposed imported = getGlobalImport(i);
			imported.recompose(recomposableElements);
		}

		// We sort the elements into ascending order.

		QuickSort2(recomposableElements, 0, recomposableElements.size() - 1);

		// We set up the global variables that will hold the recomposed
		// information.

		m_outputProperties = new OutputProperties(
				org.apache.xml.serializer.Method.UNKNOWN);
		// m_outputProperties = new OutputProperties(Method.XML);

		m_attrSets = new Hashtable();
		m_decimalFormatSymbols = new Hashtable();
		m_keyDecls = new Vector();
		m_namespaceAliasComposed = new Hashtable();
		m_templateList = new TemplateList();
		m_variables = new Vector();

		// Now we sequence through the sorted elements,
		// calling the recompose() function on each one. This will call back
		// into the
		// appropriate routine here to actually do the recomposition.
		// Note that we're going backwards, encountering the highest precedence
		// items first.
		for (int i = recomposableElements.size() - 1; i >= 0; i--)
			((ElemTemplateElement) recomposableElements.elementAt(i))
					.recompose(this);

		/*
		 * Backing out REE again, as it seems to cause some new failures which
		 * need to be investigated. -is
		 */
		// This has to be done before the initialization of the compose state,
		// because
		// eleminateRedundentGlobals will add variables to the m_variables
		// vector, which
		// it then copied in the ComposeState constructor.
		// if(true &&
		// org.apache.xalan.processor.TransformerFactoryImpl.m_optimize)
		// {
		// RedundentExprEliminator ree = new RedundentExprEliminator();
		// callVisitors(ree);
		// ree.eleminateRedundentGlobals(this);
		// }
		initComposeState();

		// Need final composition of TemplateList. This adds the wild cards onto
		// the chains.
		m_templateList.compose(this);

		// Need to clear check for properties at the same import level.
		m_outputProperties.compose(this);
		m_outputProperties.endCompose(this);

		// Now call the compose() method on every element to give it a chance to
		// adjust
		// based on composed values.

		n = getGlobalImportCount();

		for (int i = 0; i < n; i++) {
			StylesheetComposed imported = this.getGlobalImport(i);
			int includedCount = imported.getIncludeCountComposed();
			for (int j = -1; j < includedCount; j++) {
				Stylesheet included = imported.getIncludeComposed(j);
				composeTemplates(included);
			}
		}
		// Attempt to register any remaining unregistered extension namespaces.
		if (m_extNsMgr != null)
			m_extNsMgr.registerUnregisteredNamespaces();

		clearComposeState();
	}

	/**
	 * Call the compose function for each ElemTemplateElement.
	 * 
	 * @param templ
	 *            non-null reference to template element that will have the
	 *            composed method called on it, and will have it's children's
	 *            composed methods called.
	 */
	void composeTemplates(ElemTemplateElement templ)
			throws TransformerException {

		try {
			templ.compose(this);
		} catch (TransformerException ex) {
			m_errorListener.fatalError(ex);
		}

		for (ElemTemplateElement child = templ.getFirstChildElem(); child != null; child = child
				.getNextSiblingElem()) {
			try {
				composeTemplates(child);
			} catch (TransformerException ex) {
				m_errorListener.fatalError(ex);
			}
		}

		templ.endCompose(this);
	}

	/**
	 * The combined list of imports. The stylesheet with the highest import
	 * precedence will be at element 0. The one with the lowest import
	 * precedence will be at element length - 1.
	 * 
	 * @serial
	 */
	private StylesheetComposed[] m_globalImportList;

	/**
	 * Add the imports in the given sheet to the working importList vector. The
	 * will be added from highest import precedence to least import precedence.
	 * This is a post-order traversal of the import tree as described in <a
	 * href="http://www.w3.org/TR/xslt.html#import">the XSLT Recommendation</a>.
	 * <p>
	 * For example, suppose
	 * </p>
	 * <p>
	 * stylesheet A imports stylesheets B and C in that order;
	 * </p>
	 * <p>
	 * stylesheet B imports stylesheet D;
	 * </p>
	 * <p>
	 * stylesheet C imports stylesheet E.
	 * </p>
	 * <p>
	 * Then the order of import precedence (highest first) is A, C, E, B, D.
	 * </p>
	 * 
	 * @param stylesheet
	 *            Stylesheet to examine for imports.
	 * @param addToList
	 *            <code>true</code> if this template should be added to the
	 *            import list
	 * @param importList
	 *            The working import list. Templates are added here in the
	 *            reverse order of priority. When we're all done, we'll reverse
	 *            this to the correct priority in an array.
	 */
	protected void addImports(Stylesheet stylesheet, boolean addToList,
			Vector importList) {

		// Get the direct imports of this sheet.

		int n = stylesheet.getImportCount();

		if (n > 0) {
			for (int i = 0; i < n; i++) {
				Stylesheet imported = stylesheet.getImport(i);

				addImports(imported, true, importList);
			}
		}

		n = stylesheet.getIncludeCount();

		if (n > 0) {
			for (int i = 0; i < n; i++) {
				Stylesheet included = stylesheet.getInclude(i);

				addImports(included, false, importList);
			}
		}

		if (addToList)
			importList.addElement(stylesheet);

	}

	/**
	 * Get a stylesheet from the global import list. TODO: JKESS PROPOSES
	 * SPECIAL-CASE FOR NO IMPORT LIST, TO MATCH COUNT.
	 * 
	 * @param i
	 *            Index of stylesheet to get from global import list
	 * 
	 * @return The stylesheet at the given index
	 */
	public StylesheetComposed getGlobalImport(int i) {
		return m_globalImportList[i];
	}

	/**
	 * Get the total number of imports in the global import list.
	 * 
	 * @return The total number of imported stylesheets, including the root
	 *         stylesheet, thus the number will always be 1 or greater. TODO:
	 *         JKESS PROPOSES SPECIAL-CASE FOR NO IMPORT LIST, TO MATCH
	 *         DESCRIPTION.
	 */
	public int getGlobalImportCount() {
		return (m_globalImportList != null) ? m_globalImportList.length : 1;
	}

	/**
	 * Given a stylesheet, return the number of the stylesheet in the global
	 * import list.
	 * 
	 * @param sheet
	 *            The stylesheet which will be located in the global import
	 *            list.
	 * @return The index into the global import list of the given stylesheet, or
	 *         -1 if it is not found (which should never happen).
	 */
	public int getImportNumber(StylesheetComposed sheet) {

		if (this == sheet)
			return 0;

		int n = getGlobalImportCount();

		for (int i = 0; i < n; i++) {
			if (sheet == getGlobalImport(i))
				return i;
		}

		return -1;
	}

	/**
	 * This will be set up with the default values, and then the values will be
	 * set as stylesheets are encountered.
	 * 
	 * @serial
	 */
	private OutputProperties m_outputProperties;

	/**
	 * Recompose the output format object from the included elements.
	 * 
	 * @param oprops
	 *            non-null reference to xsl:output properties representation.
	 */
	void recomposeOutput(OutputProperties oprops) throws TransformerException {

		m_outputProperties.copyFrom(oprops);
	}

	/**
	 * Get the combined "xsl:output" property with the properties combined from
	 * the included stylesheets. If a xsl:output is not declared in this
	 * stylesheet or an included stylesheet, look in the imports. Please note
	 * that this returns a reference to the OutputProperties object, not a
	 * cloned object, like getOutputProperties does.
	 * 
	 * @see <a href="http://www.w3.org/TR/xslt#output">output in XSLT
	 *      Specification</a>
	 * 
	 * @return non-null reference to composed output properties object.
	 */
	public OutputProperties getOutputComposed() {

		// System.out.println("getOutputComposed.getIndent:
		// "+m_outputProperties.getIndent());
		// System.out.println("getOutputComposed.getIndenting:
		// "+m_outputProperties.getIndenting());
		return m_outputProperties;
	}

	/**
	 * Flag indicating whether an output method has been set by the user.
	 * 
	 * @serial
	 */
	private boolean m_outputMethodSet = false;

	/**
	 * Find out if an output method has been set by the user.
	 * 
	 * @return Value indicating whether an output method has been set by the
	 *         user
	 * @xsl.usage internal
	 */
	public boolean isOutputMethodSet() {
		return m_outputMethodSet;
	}

	/**
	 * Composed set of all included and imported attribute set properties. Each
	 * entry is a vector of ElemAttributeSet objects.
	 * 
	 * @serial
	 */
	private Hashtable m_attrSets;

	/**
	 * Recompose the attribute-set declarations.
	 * 
	 * @param attrSet
	 *            An attribute-set to add to the hashtable of attribute sets.
	 */
	void recomposeAttributeSets(ElemAttributeSet attrSet) {
		Vector attrSetList = (Vector) m_attrSets.get(attrSet.getName());

		if (null == attrSetList) {
			attrSetList = new Vector();

			m_attrSets.put(attrSet.getName(), attrSetList);
		}

		attrSetList.addElement(attrSet);
	}

	/**
	 * Get a list "xsl:attribute-set" properties that match the qname.
	 * 
	 * @see <a href="http://www.w3.org/TR/xslt#attribute-sets">attribute-sets in
	 *      XSLT Specification</a>
	 * 
	 * @param name
	 *            Qualified name of attribute set properties to get
	 * 
	 * @return A vector of attribute sets matching the given name
	 * 
	 * @throws ArrayIndexOutOfBoundsException
	 */
	public Vector getAttributeSetComposed(QName name)
			throws ArrayIndexOutOfBoundsException {
		return (Vector) m_attrSets.get(name);
	}

	/**
	 * Table of DecimalFormatSymbols, keyed by QName.
	 * 
	 * @serial
	 */
	private Hashtable m_decimalFormatSymbols;

	/**
	 * Recompose the decimal-format declarations.
	 * 
	 * @param dfp
	 *            A DecimalFormatProperties to add to the hashtable of decimal
	 *            formats.
	 */
	void recomposeDecimalFormats(DecimalFormatProperties dfp) {
		DecimalFormatSymbols oldDfs = (DecimalFormatSymbols) m_decimalFormatSymbols
				.get(dfp.getName());
		if (null == oldDfs) {
			m_decimalFormatSymbols.put(dfp.getName(), dfp
					.getDecimalFormatSymbols());
		} else if (!dfp.getDecimalFormatSymbols().equals(oldDfs)) {
			String themsg;
			if (dfp.getName().equals(new QName(""))) {
				// "Only one default xsl:decimal-format declaration is allowed."
				themsg = Messages
						.createMessage(
								XSLTErrorResources.WG_ONE_DEFAULT_XSLDECIMALFORMAT_ALLOWED,
								new Object[0]);
			} else {
				// "xsl:decimal-format names must be unique. Name {0} has been
				// duplicated."
				themsg = Messages
						.createMessage(
								XSLTErrorResources.WG_XSLDECIMALFORMAT_NAMES_MUST_BE_UNIQUE,
								new Object[] { dfp.getName() });
			}

			error(themsg); // Should we throw TransformerException instead?
		}

	}

	/**
	 * Given a valid element decimal-format name, return the
	 * decimalFormatSymbols with that name.
	 * <p>
	 * It is an error to declare either the default decimal-format or a
	 * decimal-format with a given name more than once (even with different
	 * import precedence), unless it is declared every time with the same value
	 * for all attributes (taking into account any default values).
	 * </p>
	 * <p>
	 * Which means, as far as I can tell, the decimal-format properties are not
	 * additive.
	 * </p>
	 * 
	 * @param name
	 *            Qualified name of the decimal format to find
	 * @return DecimalFormatSymbols object matching the given name or null if
	 *         name is not found.
	 */
	public DecimalFormatSymbols getDecimalFormatComposed(QName name) {
		return (DecimalFormatSymbols) m_decimalFormatSymbols.get(name);
	}

	/**
	 * A list of all key declarations visible from this stylesheet and all
	 * lesser stylesheets.
	 * 
	 * @serial
	 */
	private Vector m_keyDecls;

	/**
	 * Recompose the key declarations.
	 * 
	 * @param keyDecl
	 *            A KeyDeclaration to be added to the vector of key
	 *            declarations.
	 */
	void recomposeKeys(KeyDeclaration keyDecl) {
		m_keyDecls.addElement(keyDecl);
	}

	/**
	 * Get the composed "xsl:key" properties.
	 * 
	 * @see <a href="http://www.w3.org/TR/xslt#key">key in XSLT Specification</a>
	 * 
	 * @return A vector of the composed "xsl:key" properties.
	 */
	public Vector getKeysComposed() {
		return m_keyDecls;
	}

	/**
	 * Composed set of all namespace aliases.
	 * 
	 * @serial
	 */
	private Hashtable m_namespaceAliasComposed;

	/**
	 * Recompose the namespace-alias declarations.
	 * 
	 * @param nsAlias
	 *            A NamespaceAlias object to add to the hashtable of namespace
	 *            aliases.
	 */
	void recomposeNamespaceAliases(NamespaceAlias nsAlias) {
		m_namespaceAliasComposed.put(nsAlias.getStylesheetNamespace(), nsAlias);
	}

	/**
	 * Get the "xsl:namespace-alias" property. Return the NamespaceAlias for a
	 * given namespace uri.
	 * 
	 * @see <a
	 *      href="http://www.w3.org/TR/xslt#literal-result-element">literal-result-element
	 *      in XSLT Specification</a>
	 * 
	 * @param uri
	 *            non-null reference to namespace that is to be aliased.
	 * 
	 * @return NamespaceAlias that matches uri, or null if no match.
	 */
	public NamespaceAlias getNamespaceAliasComposed(String uri) {
		return (NamespaceAlias) ((null == m_namespaceAliasComposed) ? null
				: m_namespaceAliasComposed.get(uri));
	}

	/**
	 * The "xsl:template" properties.
	 * 
	 * @serial
	 */
	private TemplateList m_templateList;

	/**
	 * Recompose the template declarations.
	 * 
	 * @param template
	 *            An ElemTemplate object to add to the template list.
	 */
	void recomposeTemplates(ElemTemplate template) {
		m_templateList.setTemplate(template);
	}

	/**
	 * Accessor method to retrieve the <code>TemplateList</code> associated
	 * with this StylesheetRoot.
	 * 
	 * @return The composed <code>TemplateList</code>.
	 */
	public final TemplateList getTemplateListComposed() {
		return m_templateList;
	}

	/**
	 * Mutator method to set the <code>TemplateList</code> associated with
	 * this StylesheetRoot. This method should only be used by the compiler.
	 * Normally, the template list is built during the recompose process and
	 * should not be altered by the user.
	 * 
	 * @param templateList
	 *            The new <code>TemplateList</code> for this StylesheetRoot.
	 */
	public final void setTemplateListComposed(TemplateList templateList) {
		m_templateList = templateList;
	}

	/**
	 * Get an "xsl:template" property by node match. This looks in the imports
	 * as well as this stylesheet.
	 * 
	 * @see <a
	 *      href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules
	 *      in XSLT Specification</a>
	 * 
	 * @param xctxt
	 *            non-null reference to XPath runtime execution context.
	 * @param targetNode
	 *            non-null reference of node that the template must match.
	 * @param mode
	 *            qualified name of the node, or null.
	 * @param quietConflictWarnings
	 *            true if conflict warnings should not be reported.
	 * 
	 * @return reference to ElemTemplate that is the best match for targetNode,
	 *         or null if no match could be made.
	 * 
	 * @throws TransformerException
	 */
	public ElemTemplate getTemplateComposed(XPathContext xctxt, int targetNode,
			QName mode, boolean quietConflictWarnings, DTM dtm)
			throws TransformerException {
		return m_templateList.getTemplate(xctxt, targetNode, mode,
				quietConflictWarnings, dtm);
	}

	/**
	 * Get an "xsl:template" property by node match. This looks in the imports
	 * as well as this stylesheet.
	 * 
	 * @see <a
	 *      href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules
	 *      in XSLT Specification</a>
	 * 
	 * @param xctxt
	 *            non-null reference to XPath runtime execution context.
	 * @param targetNode
	 *            non-null reference of node that the template must match.
	 * @param mode
	 *            qualified name of the node, or null.
	 * @param maxImportLevel
	 *            The maximum importCountComposed that we should consider or -1
	 *            if we should consider all import levels. This is used by
	 *            apply-imports to access templates that have been overridden.
	 * @param endImportLevel
	 *            The count of composed imports
	 * @param quietConflictWarnings
	 *            true if conflict warnings should not be reported.
	 * 
	 * @return reference to ElemTemplate that is the best match for targetNode,
	 *         or null if no match could be made.
	 * 
	 * @throws TransformerException
	 */
	public ElemTemplate getTemplateComposed(XPathContext xctxt, int targetNode,
			QName mode, int maxImportLevel, int endImportLevel,
			boolean quietConflictWarnings, DTM dtm) throws TransformerException {
		return m_templateList.getTemplate(xctxt, targetNode, mode,
				maxImportLevel, endImportLevel, quietConflictWarnings, dtm);
	}

	/**
	 * Get an "xsl:template" property. This looks in the imports as well as this
	 * stylesheet.
	 * 
	 * @see <a
	 *      href="http://www.w3.org/TR/xslt#section-Defining-Template-Rules">section-Defining-Template-Rules
	 *      in XSLT Specification</a>
	 * 
	 * @param qname
	 *            non-null reference to qualified name of template.
	 * 
	 * @return reference to named template, or null if not found.
	 */
	public ElemTemplate getTemplateComposed(QName qname) {
		return m_templateList.getTemplate(qname);
	}

	/**
	 * Composed set of all variables and params.
	 * 
	 * @serial
	 */
	private Vector m_variables;

	/**
	 * Recompose the top level variable and parameter declarations.
	 * 
	 * @param elemVar
	 *            A top level variable or parameter to be added to the Vector.
	 */
	void recomposeVariables(ElemVariable elemVar) {
		// Don't overide higher priority variable
		if (getVariableOrParamComposed(elemVar.getName()) == null) {
			elemVar.setIsTopLevel(true); // Mark as a top-level variable or
											// param
			elemVar.setIndex(m_variables.size());
			m_variables.addElement(elemVar);
		}
	}

	/**
	 * Get an "xsl:variable" property.
	 * 
	 * @see <a
	 *      href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables
	 *      in XSLT Specification</a>
	 * 
	 * @param qname
	 *            Qualified name of variable or param
	 * 
	 * @return The ElemVariable with the given qualified name
	 */
	public ElemVariable getVariableOrParamComposed(QName qname) {
		if (null != m_variables) {
			int n = m_variables.size();

			for (int i = 0; i < n; i++) {
				ElemVariable var = (ElemVariable) m_variables.elementAt(i);
				if (var.getName().equals(qname))
					return var;
			}
		}

		return null;
	}

	/**
	 * Get all global "xsl:variable" properties in scope for this stylesheet.
	 * 
	 * @see <a
	 *      href="http://www.w3.org/TR/xslt#top-level-variables">top-level-variables
	 *      in XSLT Specification</a>
	 * 
	 * @return Vector of all variables and params in scope
	 */
	public Vector getVariablesAndParamsComposed() {
		return m_variables;
	}

	/**
	 * A list of properties that specify how to do space stripping. This uses
	 * the same exact mechanism as Templates.
	 * 
	 * @serial
	 */
	private TemplateList m_whiteSpaceInfoList;

	/**
	 * Recompose the strip-space and preserve-space declarations.
	 * 
	 * @param wsi
	 *            A WhiteSpaceInfo element to add to the list of WhiteSpaceInfo
	 *            elements.
	 */
	void recomposeWhiteSpaceInfo(WhiteSpaceInfo wsi) {
		if (null == m_whiteSpaceInfoList)
			m_whiteSpaceInfoList = new TemplateList();

		m_whiteSpaceInfoList.setTemplate(wsi);
	}

	/**
	 * Check to see if the caller should bother with check for whitespace nodes.
	 * 
	 * @return Whether the caller should bother with check for whitespace nodes.
	 */
	public boolean shouldCheckWhitespace() {
		return null != m_whiteSpaceInfoList;
	}

	/**
	 * Get information about whether or not an element should strip whitespace.
	 * 
	 * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT
	 *      Specification</a>
	 * 
	 * @param support
	 *            The XPath runtime state.
	 * @param targetElement
	 *            Element to check
	 * 
	 * @return WhiteSpaceInfo for the given element
	 * 
	 * @throws TransformerException
	 */
	public WhiteSpaceInfo getWhiteSpaceInfo(XPathContext support,
			int targetElement, DTM dtm) throws TransformerException {

		if (null != m_whiteSpaceInfoList)
			return (WhiteSpaceInfo) m_whiteSpaceInfoList.getTemplate(support,
					targetElement, null, false, dtm);
		else
			return null;
	}

	/**
	 * Get information about whether or not an element should strip whitespace.
	 * 
	 * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT
	 *      Specification</a>
	 * 
	 * @param support
	 *            The XPath runtime state.
	 * @param targetElement
	 *            Element to check
	 * 
	 * @return true if the whitespace should be stripped.
	 * 
	 * @throws TransformerException
	 */
	public boolean shouldStripWhiteSpace(XPathContext support, int targetElement)
			throws TransformerException {
		if (null != m_whiteSpaceInfoList) {
			while (DTM.NULL != targetElement) {
				DTM dtm = support.getDTM(targetElement);
				WhiteSpaceInfo info = (WhiteSpaceInfo) m_whiteSpaceInfoList
						.getTemplate(support, targetElement, null, false, dtm);
				if (null != info)
					return info.getShouldStripSpace();

				int parent = dtm.getParent(targetElement);
				if (DTM.NULL != parent
						&& DTM.ELEMENT_NODE == dtm.getNodeType(parent))
					targetElement = parent;
				else
					targetElement = DTM.NULL;
			}
		}
		return false;
	}

	/**
	 * Get information about whether or not whitespace can be stripped.
	 * 
	 * @see <a href="http://www.w3.org/TR/xslt#strip">strip in XSLT
	 *      Specification</a>
	 * 
	 * @return true if the whitespace can be stripped.
	 */
	@Override
	public boolean canStripWhiteSpace() {
		return (null != m_whiteSpaceInfoList);
	}

	/**
	 * The default template to use for text nodes if we don't find anything
	 * else. This is initialized in initDefaultRule().
	 * 
	 * @serial
	 * @xsl.usage advanced
	 */
	private ElemTemplate m_defaultTextRule;

	/**
	 * Get the default template for text.
	 * 
	 * @return the default template for text.
	 * @xsl.usage advanced
	 */
	public final ElemTemplate getDefaultTextRule() {
		return m_defaultTextRule;
	}

	/**
	 * The default template to use if we don't find anything else. This is
	 * initialized in initDefaultRule().
	 * 
	 * @serial
	 * @xsl.usage advanced
	 */
	private ElemTemplate m_defaultRule;

	/**
	 * Get the default template for elements.
	 * 
	 * @return the default template for elements.
	 * @xsl.usage advanced
	 */
	public final ElemTemplate getDefaultRule() {
		return m_defaultRule;
	}

	/**
	 * The default template to use for the root if we don't find anything else.
	 * This is initialized in initDefaultRule(). We kind of need this because
	 * the defaultRule isn't good enough because it doesn't supply a document
	 * context. For now, I default the root document element to "HTML". Don't
	 * know if this is really a good idea or not. I suspect it is not.
	 * 
	 * @serial
	 * @xsl.usage advanced
	 */
	private ElemTemplate m_defaultRootRule;

	/**
	 * Get the default template for a root node.
	 * 
	 * @return The default template for a root node.
	 * @xsl.usage advanced
	 */
	public final ElemTemplate getDefaultRootRule() {
		return m_defaultRootRule;
	}

	/**
	 * The start rule to kick off the transformation.
	 * 
	 * @serial
	 * @xsl.usage advanced
	 */
	private ElemTemplate m_startRule;

	/**
	 * Get the default template for a root node.
	 * 
	 * @return The default template for a root node.
	 * @xsl.usage advanced
	 */
	public final ElemTemplate getStartRule() {
		return m_startRule;
	}

	/**
	 * Used for default selection.
	 * 
	 * @serial
	 */
	XPath m_selectDefault;

	/**
	 * Create the default rule if needed.
	 * 
	 * @throws TransformerException
	 */
	private void initDefaultRule(ErrorListener errorListener)
			throws TransformerException {

		// Then manufacture a default
		m_defaultRule = new ElemTemplate();

		m_defaultRule.setStylesheet(this);

		XPath defMatch = new XPath("*", this, this, XPath.MATCH, errorListener);

		m_defaultRule.setMatch(defMatch);

		ElemApplyTemplates childrenElement = new ElemApplyTemplates();

		childrenElement.setIsDefaultTemplate(true);
		childrenElement.setSelect(m_selectDefault);
		m_defaultRule.appendChild(childrenElement);

		m_startRule = m_defaultRule;

		// -----------------------------
		m_defaultTextRule = new ElemTemplate();

		m_defaultTextRule.setStylesheet(this);

		defMatch = new XPath("text() | @*", this, this, XPath.MATCH,
				errorListener);

		m_defaultTextRule.setMatch(defMatch);

		ElemValueOf elemValueOf = new ElemValueOf();

		m_defaultTextRule.appendChild(elemValueOf);

		XPath selectPattern = new XPath(".", this, this, XPath.SELECT,
				errorListener);

		elemValueOf.setSelect(selectPattern);

		// --------------------------------
		m_defaultRootRule = new ElemTemplate();

		m_defaultRootRule.setStylesheet(this);

		defMatch = new XPath("/", this, this, XPath.MATCH, errorListener);

		m_defaultRootRule.setMatch(defMatch);

		childrenElement = new ElemApplyTemplates();

		childrenElement.setIsDefaultTemplate(true);
		m_defaultRootRule.appendChild(childrenElement);
		childrenElement.setSelect(m_selectDefault);
	}

	/**
	 * This is a generic version of C.A.R Hoare's Quick Sort algorithm. This
	 * will handle arrays that are already sorted, and arrays with duplicate
	 * keys. It was lifted from the NodeSorter class but should probably be
	 * eliminated and replaced with a call to Collections.sort when we migrate
	 * to Java2.<BR>
	 * 
	 * If you think of a one dimensional array as going from the lowest index on
	 * the left to the highest index on the right then the parameters to this
	 * function are lowest index or left and highest index or right. The first
	 * time you call this function it will be with the parameters 0, a.length -
	 * 1.
	 * 
	 * @param v
	 *            a vector of ElemTemplateElement elements
	 * @param lo0
	 *            left boundary of partition
	 * @param hi0
	 *            right boundary of partition
	 * 
	 */

	private void QuickSort2(Vector v, int lo0, int hi0) {
		int lo = lo0;
		int hi = hi0;

		if (hi0 > lo0) {
			// Arbitrarily establishing partition element as the midpoint of
			// the array.
			ElemTemplateElement midNode = (ElemTemplateElement) v
					.elementAt((lo0 + hi0) / 2);

			// loop through the array until indices cross
			while (lo <= hi) {
				// find the first element that is greater than or equal to
				// the partition element starting from the left Index.
				while ((lo < hi0)
						&& (((ElemTemplateElement) v.elementAt(lo))
								.compareTo(midNode) < 0)) {
					++lo;
				} // end while

				// find an element that is smaller than or equal to
				// the partition element starting from the right Index.
				while ((hi > lo0)
						&& (((ElemTemplateElement) v.elementAt(hi))
								.compareTo(midNode) > 0)) {
					--hi;
				}

				// if the indexes have not crossed, swap
				if (lo <= hi) {
					ElemTemplateElement node = (ElemTemplateElement) v
							.elementAt(lo);
					v.setElementAt(v.elementAt(hi), lo);
					v.setElementAt(node, hi);

					++lo;
					--hi;
				}
			}

			// If the right index has not reached the left side of array
			// must now sort the left partition.
			if (lo0 < hi) {
				QuickSort2(v, lo0, hi);
			}

			// If the left index has not reached the right side of array
			// must now sort the right partition.
			if (lo < hi0) {
				QuickSort2(v, lo, hi0);
			}
		}
	} // end QuickSort2 */

	private transient ComposeState m_composeState;

	/**
	 * Initialize a new ComposeState.
	 */
	void initComposeState() {
		m_composeState = new ComposeState();
	}

	/**
	 * Return class to track state global state during the compose() operation.
	 * 
	 * @return ComposeState reference, or null if endCompose has been called.
	 */
	ComposeState getComposeState() {
		return m_composeState;
	}

	/**
	 * Clear the compose state.
	 */
	private void clearComposeState() {
		m_composeState = null;
	}

	private String m_extensionHandlerClass = "org.apache.xalan.extensions.ExtensionHandlerExsltFunction";

	/**
	 * This internal method allows the setting of the java class to handle the
	 * extension function (if other than the default one).
	 * 
	 * @xsl.usage internal
	 */
	public String setExtensionHandlerClass(String handlerClassName) {
		String oldvalue = m_extensionHandlerClass;
		m_extensionHandlerClass = handlerClassName;
		return oldvalue;
	}

	/**
	 * 
	 * @xsl.usage internal
	 */
	public String getExtensionHandlerClass() {
		return m_extensionHandlerClass;
	}

	/**
	 * Class to track state global state during the compose() operation.
	 */
	class ComposeState {
		ComposeState() {
			int size = m_variables.size();
			for (int i = 0; i < size; i++) {
				ElemVariable ev = (ElemVariable) m_variables.elementAt(i);
				m_variableNames.addElement(ev.getName());
			}

		}

		private ExpandedNameTable m_ent = new ExpandedNameTable();

		/**
		 * Given a qualified name, return an integer ID that can be quickly
		 * compared.
		 * 
		 * @param qname
		 *            a qualified name object, must not be null.
		 * 
		 * @return the expanded-name id of the qualified name.
		 */
		public int getQNameID(QName qname) {

			return m_ent.getExpandedTypeID(qname.getNamespace(), qname
					.getLocalName(),
			// The type doesn't matter for our
					// purposes.
					org.apache.xml.dtm.DTM.ELEMENT_NODE);
		}

		/**
		 * A Vector of the current params and QNames within the current
		 * template. Set by ElemTemplate and used by ProcessorVariable.
		 */
		private java.util.Vector m_variableNames = new java.util.Vector();

		/**
		 * Add the name of a qualified name within the template. The position in
		 * the vector is its ID.
		 * 
		 * @param qname
		 *            A qualified name of a param or variable, should be
		 *            non-null.
		 * @return the index where the variable was added.
		 */
		int addVariableName(final org.apache.xml.utils.QName qname) {
			int pos = m_variableNames.size();
			m_variableNames.addElement(qname);
			int frameSize = m_variableNames.size() - getGlobalsSize();
			if (frameSize > m_maxStackFrameSize)
				m_maxStackFrameSize++;
			return pos;
		}

		void resetStackFrameSize() {
			m_maxStackFrameSize = 0;
		}

		int getFrameSize() {
			return m_maxStackFrameSize;
		}

		/**
		 * Get the current size of the stack frame. Use this to record the
		 * position in a template element at startElement, so that it can be
		 * popped at endElement.
		 */
		int getCurrentStackFrameSize() {
			return m_variableNames.size();
		}

		/**
		 * Set the current size of the stack frame.
		 */
		void setCurrentStackFrameSize(int sz) {
			m_variableNames.setSize(sz);
		}

		int getGlobalsSize() {
			return m_variables.size();
		}

		IntStack m_marks = new IntStack();

		void pushStackMark() {
			m_marks.push(getCurrentStackFrameSize());
		}

		void popStackMark() {
			int mark = m_marks.pop();
			setCurrentStackFrameSize(mark);
		}

		/**
		 * Get the Vector of the current params and QNames to be collected
		 * within the current template.
		 * 
		 * @return A reference to the vector of variable names. The reference
		 *         returned is owned by this class, and so should not really be
		 *         mutated, or stored anywhere.
		 */
		java.util.Vector getVariableNames() {
			return m_variableNames;
		}

		private int m_maxStackFrameSize;

	}

	/**
	 * @return Optimization flag
	 */
	public boolean getOptimizer() {
		return m_optimizer;
	}

	/**
	 * @param b
	 *            Optimization flag
	 */
	public void setOptimizer(boolean b) {
		m_optimizer = b;
	}

	/**
	 * @return Incremental flag
	 */
	public boolean getIncremental() {
		return m_incremental;
	}

	/**
	 * @return source location flag
	 */
	public boolean getSource_location() {
		return m_source_location;
	}

	/**
	 * @param b
	 *            Incremental flag
	 */
	public void setIncremental(boolean b) {
		m_incremental = b;
	}

	/**
	 * @param b
	 *            Source location flag
	 */
	public void setSource_location(boolean b) {
		m_source_location = b;
	}

}
