--- /home/cpdev/src/classpath/gnu/xml/transform/Stylesheet.java	2005-07-10 05:32:35.000000000 +0000
+++ gnu/xml/transform/Stylesheet.java	2005-06-30 05:34:21.000000000 +0000
@@ -123,7 +123,6 @@
   /**
    * Output options.
    */
-  Node output;
   int outputMethod;
   String outputVersion;
   String outputEncoding;
@@ -249,10 +248,12 @@
     Test anyNode = new NodeTypeTest((short) 0);
     List tests = Collections.singletonList(anyNode);
     builtInNodeTemplate =
-      new ApplyTemplatesNode(new Selector(Selector.CHILD, tests),
+      new ApplyTemplatesNode(null, null,
+                             new Selector(Selector.CHILD, tests),
                              null, null, null, true);
     builtInTextTemplate =
-      new ValueOfNode(new Selector(Selector.SELF, tests),
+      new ValueOfNode(null, null,
+                      new Selector(Selector.SELF, tests),
                       false);
     
     parse(doc.getDocumentElement(), true);
@@ -354,21 +355,13 @@
   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(); )
+    for (Iterator i = variables.iterator(); i.hasNext(); )
       {
         ParameterNode var = (ParameterNode) i.next();
         bindings.set(var.name,
                      var.getValue(this, null, context, 1, 1),
-                     var.type);
+                     var.global);
       }
-    current = null;
   }
 
   // -- NamespaceContext --
@@ -388,29 +381,13 @@
     // 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);
-      }
+    //System.err.println("getTemplate: mode="+mode+" context="+context);
     Set candidates = new TreeSet();
     for (Iterator j = templates.iterator(); j.hasNext(); )
       {
@@ -440,10 +417,7 @@
       {
         // Apply built-in template
         // Current template is unchanged
-        if (debug)
-          {
-            System.err.println("\tbuiltInTemplate context="+context);
-          }
+        //System.err.println("\tbuiltInTemplate context="+context);
         switch (context.getNodeType())
           {
           case Node.ELEMENT_NODE:
@@ -464,10 +438,7 @@
         Template t = (Template) candidates.iterator().next();
         // Set current template
         currentTemplate = t;
-        if (debug)
-          {
-            System.err.println("\ttemplate="+t+" context="+context);
-          }
+        //System.err.println("\ttemplate="+t+" context="+context);
         return t.node;
       }
   }
@@ -524,8 +495,7 @@
     QName mode = (mm == null) ? null : getQName(mm);
     double priority = (p == null) ? Template.DEFAULT_PRIORITY :
       Double.parseDouble(p);
-    Node children = node.getFirstChild();
-    return new Template(this, name, match, parse(children),
+    return new Template(this, name, match, parse(node.getFirstChild()),
                         precedence, priority, mode);
   }
 
@@ -535,7 +505,6 @@
   final void parseOutput(Node node, NamedNodeMap attrs)
     throws TransformerConfigurationException
   {
-    output = node;
     String method = getAttribute(attrs, "method");
     if ("xml".equals(method) || method == null)
       {
@@ -685,17 +654,11 @@
   void parse(Node node, boolean root)
     throws TransformerConfigurationException
   {
-    while (node != null)
+    if (node == null)
       {
-        current = node;
-        doParse(node, root);
-        node = node.getNextSibling();
+        return;
       }
-  }
-
-  void doParse(Node node, boolean root)
-    throws TransformerConfigurationException
-  {
+    current = node;
     try
       {
         String namespaceUri = node.getNamespaceURI();
@@ -726,21 +689,19 @@
                       }
                   }
                 parse(node.getFirstChild(), false);
+                return;
               }
             else if ("template".equals(name))
               {
-                templates.add(parseTemplate(node, attrs));
+                templates.addFirst(parseTemplate(node, attrs));
               }
             else if ("param".equals(name) ||
                      "variable".equals(name))
               {
-                int type = "variable".equals(name) ?
-                  Bindings.VARIABLE : Bindings.PARAM;
+                boolean global = "variable".equals(name);
                 TemplateNode content = parse(node.getFirstChild());
-                QName paramName =
-                  getQName(getRequiredAttribute(attrs, "name", node));
+                String paramName = getRequiredAttribute(attrs, "name", node);
                 String select = getAttribute(attrs, "select");
-                ParameterNode param;
                 if (select != null && select.length() > 0)
                   {
                     if (content != null)
@@ -751,14 +712,17 @@
                         throw new TransformerConfigurationException(msg, l);
                       }
                     Expr expr = (Expr) xpath.compile(select);
-                    param = new ParameterNode(paramName, expr, type);
+                    variables.add(new ParameterNode(null, null,
+                                                    paramName,
+                                                    expr, global));
                   }
                 else
                   {
-                    param = new ParameterNode(paramName, null, type);
-                    param.children = content;
+                    variables.add(new ParameterNode(content, null,
+                                                    paramName,
+                                                    null, global));
                   }
-                variables.add(param);
+                bindings.set(paramName, content, global);
               }
             else if ("include".equals(name) || "import".equals(name))
               {
@@ -820,6 +784,7 @@
               {
                 parseAttributeSet(node, attrs);
               }
+            parse(node.getNextSibling(), false);
           }
         else if (root)
           {
@@ -845,6 +810,7 @@
         else
           {
             // Skip unknown elements, text, comments, etc
+            parse(node.getNextSibling(), false);
           }
       }
     catch (TransformerException e)
@@ -882,6 +848,20 @@
       }
   }
 
+  final QName getQName(String name)
+  {
+    QName qName = QName.valueOf(name);
+    String prefix = qName.getPrefix();
+    String uri = qName.getNamespaceURI();
+    if (prefix != null && (uri == null || uri.length() == 0))
+      {
+        uri = getNamespaceURI(prefix);
+        String localName = qName.getLocalPart();
+        qName = new QName(uri, localName, prefix);
+      }
+    return qName;
+  }
+
   final TemplateNode parseAttributeValueTemplate(String value, Node source)
     throws TransformerConfigurationException, XPathExpressionException
   {
@@ -969,16 +949,12 @@
           {
             // Expression text
             Expr select = (Expr) xpath.compile(token);
-            TemplateNode ret2 = new ValueOfNode(select, false);
-            ret2.next = ret;
-            ret = ret2;
+            ret = new ValueOfNode(null, ret, select, false);
           }
         else
           {
             // Verbatim text
-            TemplateNode ret2 = new LiteralNode(doc.createTextNode(token));
-            ret2.next = ret;
-            ret = ret2;
+            ret = new LiteralNode(null, ret, doc.createTextNode(token));
           }
       }
     return ret;
@@ -1119,7 +1095,7 @@
   /**
    * apply-templates
    */
-  final TemplateNode parseApplyTemplates(Node node)
+  final TemplateNode parseApplyTemplates(Node node, Node children, Node next)
     throws TransformerConfigurationException, XPathExpressionException
   {
     NamedNodeMap attrs = node.getAttributes();
@@ -1130,32 +1106,32 @@
       {
         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,
+    return new ApplyTemplatesNode(null, parse(next),
+                                  select, mode,
                                   sortKeys, withParams, false);
   }
 
   /**
    * call-template
    */
-  final TemplateNode parseCallTemplate(Node node)
+  final TemplateNode parseCallTemplate(Node node, Node children, Node next)
     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);
+    return new CallTemplateNode(null, parse(next), name,
+                                withParams);
   }
   
   /**
    * value-of
    */
-  final TemplateNode parseValueOf(Node node)
+  final TemplateNode parseValueOf(Node node, Node children, Node next)
     throws TransformerConfigurationException, XPathExpressionException
   {
     NamedNodeMap attrs = node.getAttributes();
@@ -1163,59 +1139,50 @@
     String doe = getAttribute(attrs, "disable-output-escaping");
     boolean d = "yes".equals(doe);
     Expr select = (Expr) xpath.compile(s);
-    return new ValueOfNode(select, d);
+    return new ValueOfNode(null, parse(next), select, d);
   }
   
   /**
    * for-each
    */
-  final TemplateNode parseForEach(Node node)
+  final TemplateNode parseForEach(Node node, Node children, Node next)
     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;
+    return new ForEachNode(parse(children), parse(next), select, sortKeys);
   }
   
   /**
    * if
    */
-  final TemplateNode parseIf(Node node)
+  final TemplateNode parseIf(Node node, Node children, Node next)
     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;
+    return new IfNode(parse(children), parse(next), test);
   }
   
   /**
    * when
    */
-  final TemplateNode parseWhen(Node node)
+  final TemplateNode parseWhen(Node node, Node children, Node next)
     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;
+    return new WhenNode(parse(children), parse(next), test);
   }
   
   /**
    * element
    */
-  final TemplateNode parseElement(Node node)
+  final TemplateNode parseElement(Node node, Node children, Node next)
     throws TransformerConfigurationException, XPathExpressionException
   {
     NamedNodeMap attrs = node.getAttributes();
@@ -1225,16 +1192,13 @@
     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;
+    return new ElementNode(parse(children), parse(next), n, ns, uas, node);
   }
 
   /**
    * attribute
    */
-  final TemplateNode parseAttribute(Node node)
+  final TemplateNode parseAttribute(Node node, Node children, Node next)
     throws TransformerConfigurationException, XPathExpressionException
   {
     NamedNodeMap attrs = node.getAttributes();
@@ -1243,59 +1207,49 @@
     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;
+    return new AttributeNode(parse(children), parse(next), n, ns, node);
   }
   
   /**
    * text
    */
-  final TemplateNode parseText(Node node)
+  final TemplateNode parseText(Node node, Node children, Node next)
     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;
+    return new TextNode(parse(children), parse(next), d);
   }
   
   /**
    * copy
    */
-  final TemplateNode parseCopy(Node node)
+  final TemplateNode parseCopy(Node node, Node children, Node next)
     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;
+    return new CopyNode(parse(children), parse(next), uas);
   }
   
   /**
    * processing-instruction
    */
-  final TemplateNode parseProcessingInstruction(Node node)
+  final TemplateNode parseProcessingInstruction(Node node, Node children,
+                                                Node next)
     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;
+    return new ProcessingInstructionNode(parse(children),
+                                         parse(next), name);
   }
   
   /**
    * number
    */
-  final TemplateNode parseNumber(Node node)
+  final TemplateNode parseNumber(Node node, Node children, Node next)
     throws TransformerConfigurationException, XPathExpressionException
   {
     NamedNodeMap attrs = node.getAttributes();
@@ -1315,13 +1269,12 @@
     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);
+        return new NumberNode(parse(children), parse(next),
+                              value, format, lang,
+                              letterValue, gs, gz2);
       }
     else
       {
@@ -1358,42 +1311,35 @@
                 throw new TransformerConfigurationException(msg);
               }
           }
-        ret = new NodeNumberNode(level, count, from,
-                                 format, lang,
-                                 letterValue, gs, gz2);
+        return new NodeNumberNode(parse(children), parse(next),
+                                  level, count, from,
+                                  format, lang,
+                                  letterValue, gs, gz2);
       }
-    ret.children = parse(children);
-    return ret;
   }
   
   /**
    * copy-of
    */
-  final TemplateNode parseCopyOf(Node node)
+  final TemplateNode parseCopyOf(Node node, Node children, Node next)
     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;
+    return new CopyOfNode(parse(children), parse(next), select);
   }
   
   /**
    * message
    */
-  final TemplateNode parseMessage(Node node)
+  final TemplateNode parseMessage(Node node, Node children, Node next)
     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;
+    return new MessageNode(parse(children), parse(next), terminate);
   }
   
   /**
@@ -1402,34 +1348,14 @@
   final TemplateNode parse(Node node)
     throws TransformerConfigurationException
   {
-    TemplateNode first = null;
-    TemplateNode previous = null;
-    while (node != null)
+    if (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 null;
       }
-    return first;
-  }
-
-  private final TemplateNode doParse(Node node)
-    throws TransformerConfigurationException
-  {
     // Hack to associate the document function with its declaring node
     current = node;
+    Node children = node.getFirstChild();
+    Node next = node.getNextSibling();
     try
       {
         String namespaceUri = node.getNamespaceURI();
@@ -1439,85 +1365,72 @@
             String name = node.getLocalName();
             if ("apply-templates".equals(name))
               {
-                return parseApplyTemplates(node);
+                return parseApplyTemplates(node, children, next);
               }
             else if ("call-template".equals(name))
               {
-                return parseCallTemplate(node);
+                return parseCallTemplate(node, children, next);
               }
             else if ("value-of".equals(name))
               {
-                return parseValueOf(node);
+                return parseValueOf(node, children, next);
               }
             else if ("for-each".equals(name))
               {
-                return parseForEach(node);
+                return parseForEach(node, children, next);
               }
             else if ("if".equals(name))
               {
-                return parseIf(node);
+                return parseIf(node, children, next);
               }
             else if ("choose".equals(name))
               {
-                Node children = node.getFirstChild();
-                ChooseNode ret = new ChooseNode();
-                ret.children = parse(children);
-                return ret;
+                return new ChooseNode(parse(children), parse(next));
               }
             else if ("when".equals(name))
               {
-                return parseWhen(node);
+                return parseWhen(node, children, next);
               }
             else if ("otherwise".equals(name))
               {
-                Node children = node.getFirstChild();
-                OtherwiseNode ret = new OtherwiseNode();
-                ret.children = parse(children);
-                return ret;
+                return new OtherwiseNode(parse(children), parse(next));
               }
             else if ("element".equals(name))
               {
-                return parseElement(node);
+                return parseElement(node, children, next);
               }
             else if ("attribute".equals(name))
               {
-                return parseAttribute(node);
+                return parseAttribute(node, children, next);
               }
             else if ("text".equals(name))
               {
-                return parseText(node);
+                return parseText(node, children, next);
               }
             else if ("copy".equals(name))
               {
-                return parseCopy(node);
+                return parseCopy(node, children, next);
               }
             else if ("processing-instruction".equals(name))
               {
-                return parseProcessingInstruction(node);
+                return parseProcessingInstruction(node, children, next);
               }
             else if ("comment".equals(name))
               {
-                Node children = node.getFirstChild();
-                CommentNode ret = new CommentNode();
-                ret.children = parse(children);
-                return ret;
+                return new CommentNode(parse(children), parse(next));
               }
             else if ("number".equals(name))
               {
-                return parseNumber(node);
+                return parseNumber(node, children, next);
               }
             else if ("param".equals(name) ||
                      "variable".equals(name))
               {
-                int type = "variable".equals(name) ?
-                  Bindings.VARIABLE : Bindings.PARAM;
+                boolean global = "variable".equals(name);
                 NamedNodeMap attrs = node.getAttributes();
-                Node children = node.getFirstChild();
                 TemplateNode content = parse(children);
-                QName paramName = 
-                  getQName(getRequiredAttribute(attrs, "name", node));
+                String paramName = getRequiredAttribute(attrs, "name", node);
                 String select = getAttribute(attrs, "select");
-                ParameterNode ret;
                 if (select != null)
                   {
                     if (content != null)
@@ -1528,42 +1441,39 @@
                         throw new TransformerConfigurationException(msg, l);
                       }
                     Expr expr = (Expr) xpath.compile(select);
-                    ret = new ParameterNode(paramName, expr, type);
+                    return new ParameterNode(null, parse(next),
+                                             paramName, expr, global);
                   }
                 else
                   {
-                    ret = new ParameterNode(paramName, null, type);
-                    ret.children = content;
+                    return new ParameterNode(content, parse(next),
+                                             paramName, null, global);
                   }
-                return ret;
               }
             else if ("copy-of".equals(name))
               {
-                return parseCopyOf(node);
+                return parseCopyOf(node, children, next);
               }
             else if ("message".equals(name))
               {
-                return parseMessage(node);
+                return parseMessage(node, children, next);
               }
             else if ("apply-imports".equals(name))
               {
-                Node children = node.getFirstChild();
-                ApplyImportsNode ret = new ApplyImportsNode();
-                ret.children = parse(children);
-                return ret;
+                return new ApplyImportsNode(parse(children), parse(next));
               }
             else
               {
                 // xsl:fallback
                 // Pass over any other XSLT nodes
-                return null;
+                return parse(next);
               }
           }
         String prefix = node.getPrefix();
         if (extensionElementPrefixes.contains(prefix))
           {
             // Pass over extension elements
-            return null;
+            return parse(next);
           }
         switch (node.getNodeType())
           {
@@ -1573,18 +1483,13 @@
             if (!isPreserved(text))
               {
                 // Strip
-                /*String data = text.getData().trim();
-                if (data.length() > 0)
-                  {
-                    text.setData(data);
-                  } // else */
                 text.getParentNode().removeChild(text);
-                return null;
+                return parse(next);
               }
             break;
           case Node.COMMENT_NODE:
             // Ignore comments
-            return null;
+            return parse(next);
           case Node.ELEMENT_NODE:
             // Check for attribute value templates and use-attribute-sets
             NamedNodeMap attrs = node.getAttributes();
@@ -1614,7 +1519,6 @@
               {
                 // 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++)
                   {
@@ -1633,19 +1537,15 @@
                       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;
+                    child = new AttributeNode(grandchild, child, n, ns, attr);
                   }
                 String ename = node.getNodeName();
                 TemplateNode n = parseAttributeValueTemplate(ename, node);
                 TemplateNode ns = (namespaceUri == null) ? null :
                   parseAttributeValueTemplate(namespaceUri, node);
-                ElementNode ret = new ElementNode(n, ns, useAttributeSets,
-                                                  node);
-                ret.children = child;
-                return ret;
+                return new ElementNode(child, parse(next),
+                                       n, ns, useAttributeSets,
+                                       node);
               }
             // Otherwise fall through
             break;
@@ -1656,10 +1556,7 @@
         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;
+    return new LiteralNode(parse(children), parse(next), node);
   }
 
   final List parseSortKeys(Node node)
@@ -1712,8 +1609,7 @@
           {
             NamedNodeMap attrs = node.getAttributes();
             TemplateNode content = parse(node.getFirstChild());
-            QName name =
-              getQName(getRequiredAttribute(attrs, "name", node));
+            String name = getRequiredAttribute(attrs, "name", node);
             String select = getAttribute(attrs, "select");
             if (select != null)
               {
