/* Stylesheet.java -- 
   Copyright (C) 2004,2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package gnu.xml.transform;

import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeSet;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.transform.Source;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPathFunction;
import javax.xml.xpath.XPathFunctionResolver;
import javax.xml.xpath.XPathExpressionException;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.DOMException;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
import org.w3c.dom.UserDataHandler;
import gnu.xml.xpath.Expr;
import gnu.xml.xpath.NameTest;
import gnu.xml.xpath.NodeTypeTest;
import gnu.xml.xpath.Pattern;
import gnu.xml.xpath.Selector;
import gnu.xml.xpath.Root;
import gnu.xml.xpath.Test;
import gnu.xml.xpath.XPathImpl;

/**
 * An XSL stylesheet.
 *
 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
 */
class Stylesheet
  implements NamespaceContext, XPathFunctionResolver, UserDataHandler, Cloneable
{

  static final String XSL_NS = "http://www.w3.org/1999/XSL/Transform";
  private static final NameTest STYLESHEET_PRESERVE_TEXT =
    new NameTest(new QName(XSL_NS, "text"), false, false);
  
  static final int OUTPUT_XML = 0;
  static final int OUTPUT_HTML = 1;
  static final int OUTPUT_TEXT = 2;

  final TransformerFactoryImpl factory;
  TransformerImpl transformer;
  Stylesheet parent;
  final XPathImpl xpath;
  final String systemId;
  final int precedence;

  final boolean debug;

  /**
   * Version of XSLT.
   */
  String version;

  Collection extensionElementPrefixes;
  Collection excludeResultPrefixes;

  /**
   * Set of element names for which we should strip whitespace.
   */
  Set stripSpace;

  /**
   * Set of element names for which we should preserve whitespace.
   */
  Set preserveSpace;

  /**
   * Output options.
   */
  Node output;
  int outputMethod;
  String outputVersion;
  String outputEncoding;
  boolean outputOmitXmlDeclaration;
  boolean outputStandalone;
  String outputPublicId;
  String outputSystemId;
  Collection outputCdataSectionElements;
  boolean outputIndent;
  String outputMediaType;

  /**
   * Keys.
   */
  Collection keys;

  /**
   * Decimal formats.
   */
  Map decimalFormats;
  
  /**
   * Namespace aliases.
   */
  Map namespaceAliases;

  /**
   * Attribute-sets.
   */
  List attributeSets;

  /**
   * Variables.
   */
  List variables;

  /**
   * Variable and parameter bindings.
   */
  Bindings bindings;

  /**
   * Templates.
   */
  LinkedList templates;

  TemplateNode builtInNodeTemplate;
  TemplateNode builtInTextTemplate;

  /**
   * Holds the current node while parsing.
   * Necessary to associate the document function with its declaring node,
   * to resolve namespaces, and to maintain the current node for the
   * current() function.
   */
  Node current;

  /**
   * Set by a terminating message.
   */
  transient boolean terminated;

  /**
   * Current template in force.
   */
  transient Template currentTemplate;

  Stylesheet(TransformerFactoryImpl factory,
             Stylesheet parent,
             Document doc,
             String systemId,
             int precedence)
    throws TransformerConfigurationException
  {
    this.factory = factory;
    this.systemId = systemId;
    this.precedence = precedence;
    this.parent = parent;
    extensionElementPrefixes = new HashSet();
    excludeResultPrefixes = new HashSet();
    stripSpace = new LinkedHashSet();
    preserveSpace = new LinkedHashSet();
    outputCdataSectionElements = new LinkedHashSet();
    xpath = (XPathImpl) factory.xpathFactory.newXPath();
    xpath.setNamespaceContext(this);
    if (parent == null)
      {
        bindings = new Bindings(this);
        attributeSets = new LinkedList();
        variables = new LinkedList();
        namespaceAliases = new LinkedHashMap();
        templates = new LinkedList();
        keys = new LinkedList();
        decimalFormats = new LinkedHashMap();
        initDefaultDecimalFormat();
        xpath.setXPathFunctionResolver(this);
      }
    else
      {
        /* Test for import circularity */
        for (Stylesheet ctx = this; ctx.parent != null; ctx = ctx.parent)
          {
            if (systemId != null && systemId.equals(ctx.parent.systemId))
              {
                String msg = "circularity importing " + systemId;
                throw new TransformerConfigurationException(msg);
              }
          }
        /* OK */
        Stylesheet root = getRootStylesheet();
        bindings = root.bindings;
        attributeSets = root.attributeSets;
        variables = root.variables;
        namespaceAliases = root.namespaceAliases;
        templates = root.templates;
        keys = root.keys;
        decimalFormats = root.decimalFormats;
        xpath.setXPathFunctionResolver(root);
      }
    xpath.setXPathVariableResolver(bindings);

    Test anyNode = new NodeTypeTest((short) 0);
    List tests = Collections.singletonList(anyNode);
    builtInNodeTemplate =
      new ApplyTemplatesNode(new Selector(Selector.CHILD, tests),
                             null, null, null, true);
    builtInTextTemplate =
      new ValueOfNode(new Selector(Selector.SELF, tests),
                      false);
    
    parse(doc.getDocumentElement(), true);
    current = doc; // Alow namespace resolution during processing
    
    debug = ("yes".equals(System.getProperty("xsl.debug")));

    if (debug)
      {
        System.err.println("Stylesheet: " + doc.getDocumentURI());
        for (Iterator i = templates.iterator(); i.hasNext(); )
          {
            Template t = (Template) i.next();
            t.list(System.err);
            System.err.println("--------------------");
          }
      }
  }

  Stylesheet getRootStylesheet()
  {
    Stylesheet stylesheet = this;
    while (stylesheet.parent != null)
      stylesheet = stylesheet.parent;
    return stylesheet;
  }
  
  void initDefaultDecimalFormat()
  {
    DecimalFormat defaultDecimalFormat = new DecimalFormat();
    DecimalFormatSymbols symbols = new DecimalFormatSymbols();
    symbols.setDecimalSeparator('.');
    symbols.setGroupingSeparator(',');
    symbols.setPercent('%');
    symbols.setPerMill('\u2030');
    symbols.setZeroDigit('0');
    symbols.setDigit('#');
    symbols.setPatternSeparator(';');
    symbols.setInfinity("Infinity");
    symbols.setNaN("NaN");
    symbols.setMinusSign('-');
    defaultDecimalFormat.setDecimalFormatSymbols(symbols);
    decimalFormats.put(null, defaultDecimalFormat);
  }
  
  // -- Cloneable --

  public Object clone()
  {
    try
      {
        Stylesheet clone = (Stylesheet) super.clone();
        clone.bindings = (Bindings) bindings.clone();

        LinkedList templates2 = new LinkedList();
        for (Iterator i = templates.iterator(); i.hasNext(); )
          {
            Template t = (Template) i.next();
            templates2.add(t.clone(clone));
          }
        clone.templates = templates2;

        LinkedList attributeSets2 = new LinkedList();
        for (Iterator i = attributeSets.iterator(); i.hasNext(); )
          {
            AttributeSet as = (AttributeSet) i.next();
            attributeSets2.add(as.clone(clone));
          }
        clone.attributeSets = attributeSets2;

        LinkedList variables2 = new LinkedList();
        for (Iterator i = variables.iterator(); i.hasNext(); )
          {
            ParameterNode var = (ParameterNode) i.next();
            variables2.add(var.clone(clone));
          }
        clone.variables = variables2;

        LinkedList keys2 = new LinkedList();
        for (Iterator i = keys.iterator(); i.hasNext(); )
          {
            Key k = (Key) i.next();
            keys2.add(k.clone(clone));
          }
        clone.keys = keys2;
        
        return clone;
      }
    catch (CloneNotSupportedException e)
      {
        throw new Error(e.getMessage());
      }
  }

  // -- Variable evaluation --

  void initTopLevelVariables(Node context)
    throws TransformerException
  {
    current = context;
    // Sort the variables into order
    // See XSLT 11.4: "If the template or expression specifying the value of
    // a global variable x references a global variable y, then the value
    // for y must be computed before the value of x."
    List topLevel = new ArrayList(variables);
    Collections.sort(topLevel);
    for (Iterator i = topLevel.iterator(); i.hasNext(); )
      {
        ParameterNode var = (ParameterNode) i.next();
        bindings.set(var.name,
                     var.getValue(this, null, context, 1, 1),
                     var.type);
      }
    current = null;
  }

  // -- NamespaceContext --

  public String getNamespaceURI(String prefix)
  {
    return (current == null) ? null : current.lookupNamespaceURI(prefix);
  }

  public String getPrefix(String namespaceURI)
  {
    return (current == null) ? null : current.lookupPrefix(namespaceURI);
  }

  public Iterator getPrefixes(String namespaceURI)
  {
    // TODO
    return Collections.singleton(getPrefix(namespaceURI)).iterator();
  }

  final QName getQName(String name)
  {
    String localName = name, uri = null, prefix = null;
    int ci = name.indexOf(':');
    if (ci != -1)
      {
        prefix = name.substring(0, ci);
        localName = name.substring(ci + 1);
        uri = getNamespaceURI(prefix);
      }
    return new QName(uri, localName, prefix);
  }
  
  // -- Template selection --
  
  TemplateNode getTemplate(QName mode, Node context, boolean applyImports)
    throws TransformerException
  {
    if (debug)
      System.err.println("getTemplate: mode="+mode+" context="+context);
    Template selected = null;
    for (Iterator j = templates.iterator(); j.hasNext(); )
      {
        Template t = (Template) j.next();
        boolean isMatch = t.matches(mode, context);
        if (applyImports)
          {
            if (currentTemplate == null)
              {
                String msg = "current template may not be null " +
                  "during apply-imports";
                throw new TransformerException(msg);
              }
            if (!currentTemplate.imports(t))
              isMatch = false;
          }
        //System.err.println("\t"+context+" "+t+"="+isMatch);
        if (isMatch)
          {
            // Conflict resolution
            // @see http://www.w3.org/TR/xslt#conflict
            if (selected == null)
              selected = t;
            else
              {
                if (t.precedence < selected.precedence ||
                    t.priority < selected.priority)
                  continue;
                selected = t;
              }
          }
      }
    if (selected == null)
      {
        // Apply built-in template
        // Current template is unchanged
        if (debug)
          System.err.println("\tbuiltInTemplate context="+context);
        switch (context.getNodeType())
          {
          case Node.ELEMENT_NODE:
          case Node.DOCUMENT_NODE:
          case Node.DOCUMENT_FRAGMENT_NODE:
          case Node.PROCESSING_INSTRUCTION_NODE:
          case Node.COMMENT_NODE:
            return builtInNodeTemplate;
          case Node.TEXT_NODE:
          case Node.CDATA_SECTION_NODE:
          case Node.ATTRIBUTE_NODE:
            return builtInTextTemplate;
          default:
            return null;
          }
      }
    // Set current template
    currentTemplate = selected;
    if (debug)
      System.err.println("\ttemplate="+currentTemplate+" context="+context);
    return currentTemplate.node;
  }

  TemplateNode getTemplate(QName mode, QName name)
    throws TransformerException
  {
    Template selected = null;
    for (Iterator j = templates.iterator(); j.hasNext(); )
      {
        Template t = (Template) j.next();
        boolean isMatch = t.matches(name);
        if (isMatch)
          {
            // Conflict resolution
            // @see http://www.w3.org/TR/xslt#conflict
            if (selected == null)
              selected = t;
            else
              {
                if (t.precedence < selected.precedence ||
                    t.priority < selected.priority)
                  continue;
                selected = t;
              }
          }
      }
    if (selected == null)
      return null;
    return selected.node;
  }

  /**
   * template
   */
  final Template parseTemplate(Node node, NamedNodeMap attrs)
    throws TransformerConfigurationException, XPathExpressionException
  {
    String n = getAttribute(attrs, "name");
    QName name = (n == null) ? null : getQName(n);
    String m = getAttribute(attrs, "match");
    Pattern match = null;
    if (m != null)
      {
        try
          {
            match = (Pattern) xpath.compile(m);
          }
        catch (ClassCastException e)
          {
            String msg = "illegal pattern: " + m;
            throw new TransformerConfigurationException(msg);
          }
      }
    String p = getAttribute(attrs, "priority");
    String mm = getAttribute(attrs, "mode");
    QName mode = (mm == null) ? null : getQName(mm);
    Node children = node.getFirstChild();
    return new Template(this, name, match, parse(children),
                        precedence, p, mode);
  }

  /**
   * output
   */
  final void parseOutput(Node node, NamedNodeMap attrs)
    throws TransformerConfigurationException
  {
    output = node;
    String method = getAttribute(attrs, "method");
    if ("xml".equals(method) || method == null)
      outputMethod = OUTPUT_XML;
    else if ("html".equals(method))
      outputMethod = OUTPUT_HTML;
    else if ("text".equals(method))
      outputMethod = OUTPUT_TEXT;
    else
      {
        String msg = "unsupported output method: " + method;
        DOMSourceLocator l = new DOMSourceLocator(node);
        throw new TransformerConfigurationException(msg, l);
      }
    outputPublicId = getAttribute(attrs, "doctype-public");
    outputSystemId = getAttribute(attrs, "doctype-system");
    outputEncoding = getAttribute(attrs, "encoding");
    String indent = getAttribute(attrs, "indent");
    if (indent != null)
      outputIndent = "yes".equals(indent);
    outputVersion = getAttribute(attrs, "version");
    String omitXmlDecl = getAttribute(attrs, "omit-xml-declaration");
    if (omitXmlDecl != null)
      outputOmitXmlDeclaration = "yes".equals(omitXmlDecl);
    String standalone = getAttribute(attrs, "standalone");
    if (standalone != null)
      outputStandalone = "yes".equals(standalone);
    outputMediaType = getAttribute(attrs, "media-type");
    String cdataSectionElements =
      getAttribute(attrs, "cdata-section-elements");
    if (cdataSectionElements != null)
      {
        StringTokenizer st = new StringTokenizer(cdataSectionElements, " ");
        while (st.hasMoreTokens())
          outputCdataSectionElements.add(st.nextToken());
      }
  }

  /**
   * key
   */
  final void parseKey(Node node, NamedNodeMap attrs)
    throws TransformerConfigurationException, XPathExpressionException
  {
    String n = getRequiredAttribute(attrs, "name", node);
    String m = getRequiredAttribute(attrs, "match", node);
    String u = getRequiredAttribute(attrs, "use", node);
    QName name = getQName(n);
    Expr use = (Expr) xpath.compile(u);
    try
      {
        Pattern match = (Pattern) xpath.compile(m);
        Key key = new Key(name, match, use);
        keys.add(key);
      }
    catch (ClassCastException e)
      {
        throw new TransformerConfigurationException("invalid pattern: " + m);
      }
  }

  /**
   * decimal-format
   */
  final void parseDecimalFormat(Node node, NamedNodeMap attrs)
    throws TransformerConfigurationException
  {
    String dfName = getAttribute(attrs, "name");
    DecimalFormat df = new DecimalFormat();
    DecimalFormatSymbols symbols = new DecimalFormatSymbols();
    symbols.setDecimalSeparator(parseDFChar(attrs, "decimal-separator", '.'));
    symbols.setGroupingSeparator(parseDFChar(attrs, "grouping-separator", ','));
    symbols.setInfinity(parseDFString(attrs, "infinity", "Infinity"));
    symbols.setMinusSign(parseDFChar(attrs, "minus-sign", '-'));
    symbols.setNaN(parseDFString(attrs, "NaN", "NaN"));
    symbols.setPercent(parseDFChar(attrs, "percent", '%'));
    symbols.setPerMill(parseDFChar(attrs, "per-mille", '\u2030'));
    symbols.setZeroDigit(parseDFChar(attrs, "zero-digit", '0'));
    symbols.setDigit(parseDFChar(attrs, "digit", '#'));
    symbols.setPatternSeparator(parseDFChar(attrs, "pattern-separator", ';'));
    df.setDecimalFormatSymbols(symbols);
    decimalFormats.put(dfName, df);
  }

  private final char parseDFChar(NamedNodeMap attrs, String name, char def)
    throws TransformerConfigurationException
  {
    Node attr = attrs.getNamedItem(name);
    try
      {
        return (attr == null) ? def : attr.getNodeValue().charAt(0);
      }
    catch (StringIndexOutOfBoundsException e)
      {
        throw new TransformerConfigurationException("empty attribute '" +
                                                    name +
                                                    "' in decimal-format", e);
      }
  }

  private final String parseDFString(NamedNodeMap attrs, String name,
                                     String def)
  {
    Node attr = attrs.getNamedItem(name);
    return (attr == null) ? def : attr.getNodeValue();
  }
  
  /**
   * namespace-alias
   */
  final void parseNamespaceAlias(Node node, NamedNodeMap attrs)
    throws TransformerConfigurationException
  {
    String sp = getRequiredAttribute(attrs, "stylesheet-prefix", node);
    String rp = getRequiredAttribute(attrs, "result-prefix", node);
    namespaceAliases.put(sp, rp);
  }

  /**
   * attribute-set
   */
  final void parseAttributeSet(Node node, NamedNodeMap attrs)
    throws TransformerConfigurationException, XPathExpressionException
  {
    TemplateNode children = parse(node.getFirstChild());
    String name = getRequiredAttribute(attrs, "name", node);
    String uas = getAttribute(attrs, "use-attribute-sets");
    attributeSets.add(new AttributeSet(children, name, uas));
  }

  /**
   * Parse top-level elements.
   */
  void parse(Node node, boolean root)
    throws TransformerConfigurationException
  {
    while (node != null)
      {
        current = node;
        doParse(node, root);
        node = node.getNextSibling();
      }
  }

  void doParse(Node node, boolean root)
    throws TransformerConfigurationException
  {
    try
      {
        String namespaceUri = node.getNamespaceURI();
        if (XSL_NS.equals(namespaceUri) &&
            node.getNodeType() == Node.ELEMENT_NODE)
          {
            String name = node.getLocalName();
            NamedNodeMap attrs = node.getAttributes();
            if ("stylesheet".equals(name))
              {
                version = getAttribute(attrs, "version");
                String eep = getAttribute(attrs, "extension-element-prefixes");
                if (eep != null)
                  {
                    StringTokenizer st = new StringTokenizer(eep);
                    while (st.hasMoreTokens())
                      {
                        extensionElementPrefixes.add(st.nextToken());
                      }
                  }
                String erp = getAttribute(attrs, "exclude-result-prefixes");
                if (erp != null)
                  {
                    StringTokenizer st = new StringTokenizer(erp);
                    while (st.hasMoreTokens())
                      {
                        excludeResultPrefixes.add(st.nextToken());
                      }
                  }
                parse(node.getFirstChild(), false);
              }
            else if ("template".equals(name))
              templates.add(parseTemplate(node, attrs));
            else if ("param".equals(name) ||
                     "variable".equals(name))
              {
                int type = "variable".equals(name) ?
                  Bindings.VARIABLE : Bindings.PARAM;
                TemplateNode content = parse(node.getFirstChild());
                QName paramName =
                  getQName(getRequiredAttribute(attrs, "name", node));
                String select = getAttribute(attrs, "select");
                ParameterNode param;
                if (select != null && select.length() > 0)
                  {
                    if (content != null)
                      {
                        String msg = "parameter '" + paramName +
                          "' has both select and content";
                        DOMSourceLocator l = new DOMSourceLocator(node);
                        throw new TransformerConfigurationException(msg, l);
                      }
                    Expr expr = (Expr) xpath.compile(select);
                    param = new ParameterNode(paramName, expr, type);
                  }
                else
                  {
                    param = new ParameterNode(paramName, null, type);
                    param.children = content;
                  }
                variables.add(param);
              }
            else if ("include".equals(name) || "import".equals(name))
              {
                int delta = "import".equals(name) ? -1 : 0;
                String href = getRequiredAttribute(attrs, "href", node);
                Source source;
                synchronized (factory.resolver)
                  {
                    if (transformer != null)
                      {
                        factory.resolver
                          .setUserResolver(transformer.getURIResolver());
                        factory.resolver
                          .setUserListener(transformer.getErrorListener());
                      }
                    source = factory.resolver.resolve(systemId, href);
                  }
                factory.newStylesheet(source, precedence + delta, this);
              }
            else if ("output".equals(name))
              parseOutput(node, attrs);
            else if ("preserve-space".equals(name))
              {
                String elements =
                  getRequiredAttribute(attrs, "elements", node);
                StringTokenizer st = new StringTokenizer(elements,
                                                         " \t\n\r");
                while (st.hasMoreTokens())
                  {
                    NameTest element = parseNameTest(st.nextToken());
                    preserveSpace.add(new StrippingInstruction(element,
                                                               precedence));
                  }
              }
            else if ("strip-space".equals(name))
              {
                String elements =
                  getRequiredAttribute(attrs, "elements", node);
                StringTokenizer st = new StringTokenizer(elements,
                                                         " \t\n\r");
                while (st.hasMoreTokens())
                  {
                    NameTest element = parseNameTest(st.nextToken());
                    stripSpace.add(new StrippingInstruction(element, 
                                                            precedence));
                  }
              }
            else if ("key".equals(name))
              parseKey(node, attrs);
            else if ("decimal-format".equals(name))
              parseDecimalFormat(node, attrs);
            else if ("namespace-alias".equals(name))
              parseNamespaceAlias(node, attrs);
            else if ("attribute-set".equals(name))
              parseAttributeSet(node, attrs);
          }
        else if (root)
          {
            // Literal document element
            Attr versionNode =
              ((Element)node).getAttributeNodeNS(XSL_NS, "version");
            if (versionNode == null)
              {
                String msg = "no xsl:version attribute on literal result node";
                DOMSourceLocator l = new DOMSourceLocator(node);
                throw new TransformerConfigurationException(msg, l);
              }
            version = versionNode.getValue();
            Node rootClone = node.cloneNode(true);
            NamedNodeMap attrs = rootClone.getAttributes();
            attrs.removeNamedItemNS(XSL_NS, "version");
            templates.add(new Template(this, null, new Root(),
                                       parse(rootClone),
                                       precedence,
                                       null,
                                       null));
          }
        else
          {
            // Skip unknown elements, text, comments, etc
          }
      }
    catch (TransformerException e)
      {
        DOMSourceLocator l = new DOMSourceLocator(node);
        throw new TransformerConfigurationException(e.getMessage(), l, e);
      }
    catch (DOMException e)
      {
        DOMSourceLocator l = new DOMSourceLocator(node);
        throw new TransformerConfigurationException(e.getMessage(), l, e);
      }
    catch (XPathExpressionException e)
      {
        DOMSourceLocator l = new DOMSourceLocator(node);
        throw new TransformerConfigurationException(e.getMessage(), l, e);
      }
  }

  final NameTest parseNameTest(String token)
  {
    if ("*".equals(token))
      return new NameTest(null, true, true);
    else if (token.endsWith(":*"))
      {
        QName qName = getQName(token);
        return new NameTest(qName, true, false);
      }
    else
      {
        QName qName = getQName(token);
        return new NameTest(qName, false, false);
      }
  }

  final TemplateNode parseAttributeValueTemplate(String value, Node source)
    throws TransformerConfigurationException, XPathExpressionException
  {
    current = source;
    // Tokenize
    int len = value.length();
    int off = 0;
    List tokens = new ArrayList(); // text tokens
    List types = new ArrayList(); // literal or expression
    int depth = 0;
    for (int i = 0; i < len; i++)
      {
        char c = value.charAt(i);
        if (c == '{')
          {
            if (i < (len - 1) && value.charAt(i + 1) == '{')
              {
                tokens.add(value.substring(off, i + 1));
                types.add(Boolean.FALSE);
                i++;
                off = i + 1;
                continue;
              }
            if (depth == 0)
              {
                if (i - off > 0)
                  {
                    tokens.add(value.substring(off, i));
                    types.add(Boolean.FALSE);
                  }
                off = i + 1;
              }
            depth++;
          }
        else if (c == '}')
          {
            if (i < (len - 1) && value.charAt(i + 1) == '}')
              {
                tokens.add(value.substring(off, i + 1));
                types.add(Boolean.FALSE);
                i++;
                off = i + 1;
                continue;
              }
            if (depth == 1)
              {
                if (i - off > 0)
                  {
                    tokens.add(value.substring(off, i));
                    types.add(Boolean.TRUE);
                  }
                else
                  {
                    String msg = "attribute value template " +
                      "must contain expression: " + value;
                    DOMSourceLocator l = new DOMSourceLocator(source);
                    throw new TransformerConfigurationException(msg, l);
                  }
                off = i + 1;
              }
            depth--;
          }
      }
    if (depth > 0)
      {
        String msg = "invalid attribute value template: " + value;
        throw new TransformerConfigurationException(msg);
      }
    if (len - off > 0)
      {
        // Trailing text
        tokens.add(value.substring(off));
        types.add(Boolean.FALSE);
      }
    
    // Construct template node tree
    TemplateNode ret = null;
    Document doc = source.getOwnerDocument();
    len = tokens.size();
    for (int i = len - 1; i >= 0; i--)
      {
        String token = (String) tokens.get(i);
        Boolean type = (Boolean) types.get(i);
        if (type == Boolean.TRUE)
          {
            // Expression text
            Expr select = (Expr) xpath.compile(token);
            TemplateNode ret2 = new ValueOfNode(select, false);
            ret2.next = ret;
            ret = ret2;
          }
        else
          {
            // Verbatim text
            TemplateNode ret2 = new LiteralNode(doc.createTextNode(token));
            ret2.next = ret;
            ret = ret2;
          }
      }
    return ret;
  }

  /**
   * Whitespace stripping.
   * @param text the text node
   * @param source true if a source node, false if a stylesheet text node
   * @see http://www.w3.org/TR/xslt#strip
   */
  boolean isPreserved(Text text, boolean source)
    throws TransformerConfigurationException
  {
    // Check characters in text
    String value = text.getData();
    if (value != null)
      {
        int len = value.length();
        for (int i = 0; i < len; i++)
          {
            char c = value.charAt(i);
            if (c != 0x20 && c != 0x09 && c != 0x0a && c != 0x0d)
              return true;
          }
      }
    // Check parent node
    Node ctx = text.getParentNode();
    if (source)
      {
        // Source document text node
        boolean preserve = true;
        float psPriority = 0.0f, ssPriority = 0.0f;
        if (!stripSpace.isEmpty())
          {
            // Conflict resolution
            StrippingInstruction ssi = null, psi = null;
            for (Iterator i = stripSpace.iterator(); i.hasNext(); )
              {
                StrippingInstruction si = (StrippingInstruction) i.next();
                if (si.element.matches(ctx, 1, 1))
                  {
                    if (ssi != null)
                      {
                        if (si.precedence < ssi.precedence)
                          continue;
                        float p = si.getPriority();
                        if (p < ssPriority)
                          continue;
                      }
                    ssi = si;
                  }
              }
            for (Iterator i = preserveSpace.iterator(); i.hasNext(); )
              {
                StrippingInstruction si = (StrippingInstruction) i.next();
                if (si.element.matches(ctx, 1, 1))
                  {
                    if (psi != null)
                      {
                        if (si.precedence < psi.precedence)
                          continue;
                        float p = si.getPriority();
                        if (p < psPriority)
                          continue;
                      }
                    psi = si;
                  }
              }
            if (ssi != null)
              {
                if (psi != null)
                  {
                    if (psi.precedence < ssi.precedence)
                      preserve = false;
                    else if (psPriority < ssPriority)
                      preserve = false;
                  }
                else
                  preserve = false;
              }
          }
        if (preserve)
          return true;
      }
    else
      {
        // Stylesheet text node
        if (STYLESHEET_PRESERVE_TEXT.matches(ctx, 1, 1))
          return true;
      }
    // Check whether any ancestor specified xml:space
    while (ctx != null)
      {
        if (ctx.getNodeType() == Node.ELEMENT_NODE)
          {
            Element element = (Element) ctx;
            String xmlSpace = element.getAttribute("xml:space");
            if ("default".equals(xmlSpace))
              break;
            else if ("preserve".equals(xmlSpace))
              return true;
            else if (xmlSpace.length() > 0)
              {
                String msg = "Illegal value for xml:space: " + xmlSpace;
                throw new TransformerConfigurationException(msg);
              }
          }
        ctx = ctx.getParentNode();
      }
    return false;
  }

  public XPathFunction resolveFunction(QName name, int arity)
  {
    String uri = name.getNamespaceURI();
    if (XSL_NS.equals(uri) || uri == null || uri.length() == 0)
      {
        String localName = name.getLocalPart();
        if ("document".equals(localName) && (arity == 1 || arity == 2))
          {
            if (current == null)
                throw new RuntimeException("current is null");
            return new DocumentFunction(getRootStylesheet(), current);
          }
        else if ("key".equals(localName) && (arity == 2))
          return new KeyFunction(getRootStylesheet());
        else if ("format-number".equals(localName) &&
                 (arity == 2 || arity == 3))
          return new FormatNumberFunction(getRootStylesheet());
        else if ("current".equals(localName) && (arity == 0))
          return new CurrentFunction(getRootStylesheet());
        else if ("unparsed-entity-uri".equals(localName) && (arity == 1))
          return new UnparsedEntityUriFunction();
        else if ("generate-id".equals(localName) &&
                 (arity == 1 || arity == 0))
          return new GenerateIdFunction();
        else if ("system-property".equals(localName) && (arity == 1))
          return new SystemPropertyFunction();
        else if ("element-available".equals(localName) && (arity == 1))
          return new ElementAvailableFunction(new NamespaceProxy(current));
        else if ("function-available".equals(localName) && (arity == 1))
          return new FunctionAvailableFunction(new NamespaceProxy(current));
      }
    return null;
  }
  
  // -- Parsing --

  /**
   * apply-templates
   */
  final TemplateNode parseApplyTemplates(Node node)
    throws TransformerConfigurationException, XPathExpressionException
  {
    NamedNodeMap attrs = node.getAttributes();
    String m = getAttribute(attrs, "mode");
    QName mode = (m == null) ? null : getQName(m);
    String s = getAttribute(attrs, "select");
    if (s == null)
      s = "child::node()";
    Node children = node.getFirstChild();
    List sortKeys = parseSortKeys(children);
    List withParams = parseWithParams(children);
    Expr select = (Expr) xpath.compile(s);
    return new ApplyTemplatesNode(select, mode,
                                  sortKeys, withParams, false);
  }

  /**
   * call-template
   */
  final TemplateNode parseCallTemplate(Node node)
    throws TransformerConfigurationException, XPathExpressionException
  {
    NamedNodeMap attrs = node.getAttributes();
    String n = getRequiredAttribute(attrs, "name", node);
    QName name = getQName(n);
    Node children = node.getFirstChild();
    List withParams = parseWithParams(children);
    return new CallTemplateNode(name, withParams);
  }
  
  /**
   * value-of
   */
  final TemplateNode parseValueOf(Node node)
    throws TransformerConfigurationException, XPathExpressionException
  {
    NamedNodeMap attrs = node.getAttributes();
    String s = getRequiredAttribute(attrs, "select", node);
    String doe = getAttribute(attrs, "disable-output-escaping");
    boolean d = "yes".equals(doe);
    Expr select = (Expr) xpath.compile(s);
    return new ValueOfNode(select, d);
  }
  
  /**
   * for-each
   */
  final TemplateNode parseForEach(Node node)
    throws TransformerConfigurationException, XPathExpressionException
  {
    NamedNodeMap attrs = node.getAttributes();
    String s = getRequiredAttribute(attrs, "select", node);
    Node children = node.getFirstChild();
    List sortKeys = parseSortKeys(children);
    Expr select = (Expr) xpath.compile(s);
    ForEachNode ret = new ForEachNode(select, sortKeys);
    ret.children = parse(children);
    return ret;
  }
  
  /**
   * if
   */
  final TemplateNode parseIf(Node node)
    throws TransformerConfigurationException, XPathExpressionException
  {
    NamedNodeMap attrs = node.getAttributes();
    String t = getRequiredAttribute(attrs, "test", node);
    Expr test = (Expr) xpath.compile(t);
    Node children = node.getFirstChild();
    IfNode ret = new IfNode(test);
    ret.children = parse(children);
    return ret;
  }
  
  /**
   * when
   */
  final TemplateNode parseWhen(Node node)
    throws TransformerConfigurationException, XPathExpressionException
  {
    NamedNodeMap attrs = node.getAttributes();
    String t = getRequiredAttribute(attrs, "test", node);
    Expr test = (Expr) xpath.compile(t);
    Node children = node.getFirstChild();
    WhenNode ret = new WhenNode(test);
    ret.children = parse(children);
    return ret;
  }
  
  /**
   * element
   */
  final TemplateNode parseElement(Node node)
    throws TransformerConfigurationException, XPathExpressionException
  {
    NamedNodeMap attrs = node.getAttributes();
    String name = getRequiredAttribute(attrs, "name", node);
    String namespace = getAttribute(attrs, "namespace");
    String uas = getAttribute(attrs, "use-attribute-sets");
    TemplateNode n = parseAttributeValueTemplate(name, node);
    TemplateNode ns = (namespace == null) ? null :
      parseAttributeValueTemplate(namespace, node);
    Node children = node.getFirstChild();
    ElementNode ret = new ElementNode(n, ns, uas, node);
    ret.children = parse(children);
    return ret;
  }

  /**
   * attribute
   */
  final TemplateNode parseAttribute(Node node)
    throws TransformerConfigurationException, XPathExpressionException
  {
    NamedNodeMap attrs = node.getAttributes();
    String name = getRequiredAttribute(attrs, "name", node);
    String namespace = getAttribute(attrs, "namespace");
    TemplateNode n = parseAttributeValueTemplate(name, node);
    TemplateNode ns = (namespace == null) ? null :
      parseAttributeValueTemplate(namespace, node);
    Node children = node.getFirstChild();
    AttributeNode ret = new AttributeNode(n, ns, node);
    ret.children = parse(children);
    return ret;
  }
  
  /**
   * text
   */
  final TemplateNode parseText(Node node)
    throws TransformerConfigurationException, XPathExpressionException
  {
    NamedNodeMap attrs = node.getAttributes();
    String doe = getAttribute(attrs, "disable-output-escaping");
    boolean d = "yes".equals(doe);
    Node children = node.getFirstChild();
    TextNode ret = new TextNode(d);
    ret.children = parse(children);
    return ret;
  }
  
  /**
   * copy
   */
  final TemplateNode parseCopy(Node node)
    throws TransformerConfigurationException, XPathExpressionException
  {
    NamedNodeMap attrs = node.getAttributes();
    String uas = getAttribute(attrs, "use-attribute-sets");
    Node children = node.getFirstChild();
    CopyNode ret = new CopyNode(uas);
    ret.children = parse(children);
    return ret;
  }
  
  /**
   * processing-instruction
   */
  final TemplateNode parseProcessingInstruction(Node node)
    throws TransformerConfigurationException, XPathExpressionException
  {
    NamedNodeMap attrs = node.getAttributes();
    String name = getRequiredAttribute(attrs, "name", node);
    Node children = node.getFirstChild();
    ProcessingInstructionNode ret = new ProcessingInstructionNode(name);
    ret.children = parse(children);
    return ret;
  }
  
  /**
   * number
   */
  final TemplateNode parseNumber(Node node)
    throws TransformerConfigurationException, XPathExpressionException
  {
    NamedNodeMap attrs = node.getAttributes();
    String v = getAttribute(attrs, "value");
    String ff = getAttribute(attrs, "format");
    if (ff == null)
      {
        ff = "1";
      }
    TemplateNode format = parseAttributeValueTemplate(ff, node);
    String lang = getAttribute(attrs, "lang");
    String lv = getAttribute(attrs, "letter-value");
    int letterValue = "traditional".equals(lv) ?
      AbstractNumberNode.TRADITIONAL :
      AbstractNumberNode.ALPHABETIC;
    String gs = getAttribute(attrs, "grouping-separator");
    String gz = getAttribute(attrs, "grouping-size");
    int gz2 = (gz != null && gz.length() > 0) ?
      Integer.parseInt(gz) : 1;
    Node children = node.getFirstChild();
    TemplateNode ret;
    if (v != null && v.length() > 0)
      {
        Expr value = (Expr) xpath.compile(v);
        ret = new NumberNode(value, format, lang,
                             letterValue, gs, gz2);
      }
    else
      {
        String l = getAttribute(attrs, "level");
        int level =
          "multiple".equals(l) ? NodeNumberNode.MULTIPLE :
                      "any".equals(l) ? NodeNumberNode.ANY :
                      NodeNumberNode.SINGLE;
        String c = getAttribute(attrs, "count");
        String f = getAttribute(attrs, "from");
        Pattern count = null;
        Pattern from = null;
        if (c != null)
          {
            try
              {
                count = (Pattern) xpath.compile(c);
              }
            catch (ClassCastException e)
              {
                String msg = "invalid pattern: " + c;
                throw new TransformerConfigurationException(msg);
              }
          }
        if (f != null)
          {
            try
              {
                from = (Pattern) xpath.compile(f);
              }
            catch (ClassCastException e)
              {
                String msg = "invalid pattern: " + f;
                throw new TransformerConfigurationException(msg);
              }
          }
        ret = new NodeNumberNode(level, count, from,
                                 format, lang,
                                 letterValue, gs, gz2);
      }
    ret.children = parse(children);
    return ret;
  }
  
  /**
   * copy-of
   */
  final TemplateNode parseCopyOf(Node node)
    throws TransformerConfigurationException, XPathExpressionException
  {
    NamedNodeMap attrs = node.getAttributes();
    String s = getRequiredAttribute(attrs, "select", node);
    Expr select = (Expr) xpath.compile(s);
    Node children = node.getFirstChild();
    CopyOfNode ret = new CopyOfNode(select);
    ret.children = parse(children);
    return ret;
  }
  
  /**
   * message
   */
  final TemplateNode parseMessage(Node node)
    throws TransformerConfigurationException, XPathExpressionException
  {
    NamedNodeMap attrs = node.getAttributes();
    String t = getAttribute(attrs, "terminate");
    boolean terminate = "yes".equals(t);
    Node children = node.getFirstChild();
    MessageNode ret = new MessageNode(terminate);
    ret.children = parse(children);
    return ret;
  }
  
  /**
   * Parse template-level elements.
   */
  final TemplateNode parse(Node node)
    throws TransformerConfigurationException
  {
    TemplateNode first = null;
    TemplateNode previous = null;
    while (node != null)
      {
        Node next = node.getNextSibling();
        TemplateNode tnode = doParse(node);
        if (tnode != null)
          {
            if (first == null)
              first = tnode;
            if (previous != null)
              previous.next = tnode;
            previous = tnode;
          }
        node = next;
      }
    return first;
  }

  private final TemplateNode doParse(Node node)
    throws TransformerConfigurationException
  {
    // Hack to associate the document function with its declaring node
    current = node;
    try
      {
        String namespaceUri = node.getNamespaceURI();
        if (Stylesheet.XSL_NS.equals(namespaceUri) &&
            Node.ELEMENT_NODE == node.getNodeType())
          {
            String name = node.getLocalName();
            if ("apply-templates".equals(name))
              return parseApplyTemplates(node);
            else if ("call-template".equals(name))
              return parseCallTemplate(node);
            else if ("value-of".equals(name))
              return parseValueOf(node);
            else if ("for-each".equals(name))
              return parseForEach(node);
            else if ("if".equals(name))
              return parseIf(node);
            else if ("choose".equals(name))
              {
                Node children = node.getFirstChild();
                ChooseNode ret = new ChooseNode();
                ret.children = parse(children);
                return ret;
              }
            else if ("when".equals(name))
              return parseWhen(node);
            else if ("otherwise".equals(name))
              {
                Node children = node.getFirstChild();
                OtherwiseNode ret = new OtherwiseNode();
                ret.children = parse(children);
                return ret;
              }
            else if ("element".equals(name))
              return parseElement(node);
            else if ("attribute".equals(name))
              return parseAttribute(node);
            else if ("text".equals(name))
              return parseText(node);
            else if ("copy".equals(name))
              return parseCopy(node);
            else if ("processing-instruction".equals(name))
              return parseProcessingInstruction(node);
            else if ("comment".equals(name))
              {
                Node children = node.getFirstChild();
                CommentNode ret = new CommentNode();
                ret.children = parse(children);
                return ret;
              }
            else if ("number".equals(name))
              return parseNumber(node);
            else if ("param".equals(name) ||
                     "variable".equals(name))
              {
                int type = "variable".equals(name) ?
                  Bindings.VARIABLE : Bindings.PARAM;
                NamedNodeMap attrs = node.getAttributes();
                Node children = node.getFirstChild();
                TemplateNode content = parse(children);
                QName paramName = 
                  getQName(getRequiredAttribute(attrs, "name", node));
                String select = getAttribute(attrs, "select");
                ParameterNode ret;
                if (select != null)
                  {
                    if (content != null)
                      {
                        String msg = "parameter '" + paramName +
                          "' has both select and content";
                        DOMSourceLocator l = new DOMSourceLocator(node);
                        throw new TransformerConfigurationException(msg, l);
                      }
                    Expr expr = (Expr) xpath.compile(select);
                    ret = new ParameterNode(paramName, expr, type);
                  }
                else
                  {
                    ret = new ParameterNode(paramName, null, type);
                    ret.children = content;
                  }
                return ret;
              }
            else if ("copy-of".equals(name))
              return parseCopyOf(node);
            else if ("message".equals(name))
              return parseMessage(node);
            else if ("apply-imports".equals(name))
              {
                Node children = node.getFirstChild();
                ApplyImportsNode ret = new ApplyImportsNode();
                ret.children = parse(children);
                return ret;
              }
            else
              {
                // xsl:fallback
                // Pass over any other XSLT nodes
                return null;
              }
          }
        String prefix = node.getPrefix();
        if (extensionElementPrefixes.contains(prefix))
          {
            // Check for xsl:fallback
            for (Node ctx = node.getFirstChild(); ctx != null;
                 ctx = ctx.getNextSibling())
              {
                String ctxUri = ctx.getNamespaceURI();
                if (XSL_NS.equals(ctxUri) &&
                    "fallback".equals(ctx.getLocalName()))
                  {
                    ctx = ctx.getFirstChild();
                    return (ctx == null) ? null : parse(ctx);
                  }
              }
            // Otherwise pass over extension element
            return null;
          }
        switch (node.getNodeType())
          {
          case Node.TEXT_NODE:
          case Node.CDATA_SECTION_NODE:
            // Determine whether to strip whitespace
            Text text = (Text) node;
            if (!isPreserved(text, false))
              {
                // Strip
                text.getParentNode().removeChild(text);
                return null;
              }
            break;
          case Node.COMMENT_NODE:
            // Ignore comments
            return null;
          case Node.ELEMENT_NODE:
            // Check for attribute value templates and use-attribute-sets
            NamedNodeMap attrs = node.getAttributes();
            boolean convert = false;
            String useAttributeSets = null;
            int len = attrs.getLength();
            for (int i = 0; i < len; i++)
              {
                Node attr = attrs.item(i);
                String value = attr.getNodeValue();
                if (Stylesheet.XSL_NS.equals(attr.getNamespaceURI()) &&
                    "use-attribute-sets".equals(attr.getLocalName()))
                  {
                    useAttributeSets = value;
                    convert = true;
                    break;
                  }
                int start = value.indexOf('{');
                int end = value.indexOf('}');
                if (start != -1 || end != -1)
                  {
                    convert = true;
                    break;
                  }
              }
            if (convert)
              {
                // Create an element-producing template node instead
                // with appropriate attribute-producing child template nodes
                Node children = node.getFirstChild();
                TemplateNode child = parse(children);
                for (int i = 0; i < len; i++)
                  {
                    Node attr = attrs.item(i);
                    String ans = attr.getNamespaceURI();
                    String aname = attr.getNodeName();
                    if (Stylesheet.XSL_NS.equals(ans) &&
                        "use-attribute-sets".equals(attr.getLocalName()))
                      continue;
                    String value = attr.getNodeValue();
                    TemplateNode grandchild =
                      parseAttributeValueTemplate(value, node);
                    TemplateNode n =
                      parseAttributeValueTemplate(aname, node);
                    TemplateNode ns = (ans == null) ? null :
                      parseAttributeValueTemplate(ans, node);
                    TemplateNode newChild = new AttributeNode(n, ns, attr);
                    newChild.children = grandchild;
                    newChild.next = child;
                    child = newChild;
                  }
                String ename = node.getNodeName();
                TemplateNode n = parseAttributeValueTemplate(ename, node);
                //TemplateNode ns = (namespaceUri == null) ? null :
                //  parseAttributeValueTemplate(namespaceUri, node);
                TemplateNode ns = null;
                ElementNode ret = new ElementNode(n, ns, useAttributeSets,
                                                  node);
                ret.children = child;
                return ret;
              }
            // Otherwise fall through
            break;
          }
      }
    catch (XPathExpressionException e)
      {
        DOMSourceLocator l = new DOMSourceLocator(node);
        throw new TransformerConfigurationException(e.getMessage(), l, e);
      }
    Node children = node.getFirstChild();
    LiteralNode ret = new LiteralNode(node);
    ret.children = parse(children);
    return ret;
  }

  final List parseSortKeys(Node node)
    throws TransformerConfigurationException, XPathExpressionException
  {
    List ret = new LinkedList();
    while (node != null)
      {
        String namespaceUri = node.getNamespaceURI();
        if (Stylesheet.XSL_NS.equals(namespaceUri) &&
            Node.ELEMENT_NODE == node.getNodeType() &&
            "sort".equals(node.getLocalName()))
          {
            NamedNodeMap attrs = node.getAttributes();
            String s = getAttribute(attrs, "select");
            if (s == null)
              s = ".";
            Expr select = (Expr) xpath.compile(s);
            String l = getAttribute(attrs, "lang");
            TemplateNode lang = (l == null) ? null :
              parseAttributeValueTemplate(l, node);
            String dt = getAttribute(attrs, "data-type");
            TemplateNode dataType = (dt == null) ? null :
              parseAttributeValueTemplate(dt, node);
            String o = getAttribute(attrs, "order");
            TemplateNode order = (o == null) ? null :
              parseAttributeValueTemplate(o, node);
            String co = getAttribute(attrs, "case-order");
            TemplateNode caseOrder = (co == null) ? null :
              parseAttributeValueTemplate(co, node);
            ret.add(new SortKey(select, lang, dataType, order, caseOrder));
          }
        node = node.getNextSibling();
      }
    return ret.isEmpty() ? null : ret;
  }

  final List parseWithParams(Node node)
    throws TransformerConfigurationException, XPathExpressionException
  {
    List ret = new LinkedList();
    while (node != null)
      {
        String namespaceUri = node.getNamespaceURI();
        if (Stylesheet.XSL_NS.equals(namespaceUri) &&
            Node.ELEMENT_NODE == node.getNodeType() &&
            "with-param".equals(node.getLocalName()))
          {
            NamedNodeMap attrs = node.getAttributes();
            TemplateNode content = parse(node.getFirstChild());
            QName name =
              getQName(getRequiredAttribute(attrs, "name", node));
            String select = getAttribute(attrs, "select");
            if (select != null)
              {
                if (content != null)
                  {
                    String msg = "parameter '" + name +
                      "' has both select and content";
                    DOMSourceLocator l = new DOMSourceLocator(node);
                    throw new TransformerConfigurationException(msg, l);
                  }
                Expr expr = (Expr) xpath.compile(select);
                ret.add(new WithParam(name, expr));
              }
            else
              ret.add(new WithParam(name, content));
          }
        node = node.getNextSibling();
      }
    return ret.isEmpty() ? null : ret;
  }

  /**
   * Created element nodes have a copy of the namespace nodes in the
   * stylesheet, except the XSLT namespace, extension namespaces, and
   * exclude-result-prefixes.
   */
  final void addNamespaceNodes(Node source, Node target, Document doc,
                               Collection elementExcludeResultPrefixes)
  {
    NamedNodeMap attrs = source.getAttributes();
    if (attrs != null)
      {
        int len = attrs.getLength();
        for (int i = 0; i < len; i++)
          {
            Node attr = attrs.item(i);
            String uri = attr.getNamespaceURI();
            if (uri == XMLConstants.XMLNS_ATTRIBUTE_NS_URI)
              {
                String prefix = attr.getLocalName();
                if (XMLConstants.XMLNS_ATTRIBUTE.equals(prefix))
                  prefix = "#default";
                String ns = attr.getNodeValue();
                // Should the namespace be excluded?
                if (XSL_NS.equals(ns) ||
                    extensionElementPrefixes.contains(prefix) ||
                    elementExcludeResultPrefixes.contains(prefix) ||
                    excludeResultPrefixes.contains(prefix))
                  continue;
                // Is the namespace already defined on the target?
                if (prefix == "#default")
                  prefix = null;
                if (target.lookupNamespaceURI(prefix) != null)
                  continue;
                attr = attr.cloneNode(true);
                attr = doc.adoptNode(attr);
                target.getAttributes().setNamedItemNS(attr);
              }
          }
      }
    Node parent = source.getParentNode();
    if (parent != null)
      addNamespaceNodes(parent, target, doc, elementExcludeResultPrefixes);
  }

  static final String getAttribute(NamedNodeMap attrs, String name)
  {
    Node attr = attrs.getNamedItem(name);
    if (attr == null)
      return null;
    String ret = attr.getNodeValue();
    if (ret.length() == 0)
      return null;
    return ret;
  }

  static final String getRequiredAttribute(NamedNodeMap attrs, String name,
                                           Node source)
    throws TransformerConfigurationException
  {
    String value = getAttribute(attrs, name);
    if (value == null || value.length() == 0)
      {
        String msg =
          name + " attribute is required on " + source.getNodeName();
        DOMSourceLocator l = new DOMSourceLocator(source);
        throw new TransformerConfigurationException(msg, l);
      }
    return value;
  }

  // Handle user data changes when nodes are cloned etc

  public void handle(short op, String key, Object data, Node src, Node dst)
  {
    dst.setUserData(key, data, this);
  }

}

