First version for Xalan3 branch!

diff --git a/src/org/apache/xalan/processor/ProcessorFuncResult.java b/src/org/apache/xalan/processor/ProcessorFuncResult.java
new file mode 100644
index 0000000..fed6558
--- /dev/null
+++ b/src/org/apache/xalan/processor/ProcessorFuncResult.java
@@ -0,0 +1,103 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Xalan" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999, Lotus
+ * Development Corporation., http://www.lotus.com.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package org.apache.xalan.processor;
+
+import org.apache.xalan.templates.ElemTemplateElement;
+import org.apache.xalan.templates.ElemFunction;
+import org.apache.xalan.templates.ElemFuncResult;
+import org.apache.xalan.templates.ElemVariable;
+import org.apache.xalan.templates.ElemParam;
+import org.apache.xalan.templates.ElemFallback;
+import org.apache.xalan.res.XSLTErrorResources;
+
+import javax.xml.transform.TransformerException;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.NoSuchMethodException;
+import java.lang.InstantiationException;
+import java.lang.IllegalAccessException;
+
+import java.util.Vector;
+
+/**
+ * <meta name="usage" content="internal"/>
+ * This class processes parse events for an exslt func:result element.
+ */
+public class ProcessorFuncResult extends ProcessorTemplateElem
+{
+  
+  /**
+   * Verify that the parent of  xsl:result is an xsl:function element.
+   */
+  public void startElement(
+          StylesheetHandler handler, String uri, String localName, String rawName, Attributes attributes)
+            throws SAXException
+  {
+    String msg = "";
+
+    super.startElement(handler, uri, localName, rawName, attributes);
+    ElemTemplateElement parent = handler.getElemTemplateElement().getParentElem();
+    if (!(parent instanceof ElemFunction))
+    {
+      msg = "xsl:result must be the last child of an xsl:function element";
+      handler.error(msg, new SAXException(msg));
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/org/apache/xalan/processor/ProcessorFunction.java b/src/org/apache/xalan/processor/ProcessorFunction.java
new file mode 100644
index 0000000..6f4bf08
--- /dev/null
+++ b/src/org/apache/xalan/processor/ProcessorFunction.java
@@ -0,0 +1,213 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Xalan" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999, Lotus
+ * Development Corporation., http://www.lotus.com.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package org.apache.xalan.processor;
+
+import org.apache.xalan.templates.ElemLiteralResult;
+import org.apache.xalan.templates.ElemElement;
+import org.apache.xalan.templates.ElemTemplateElement;
+import org.apache.xalan.templates.Stylesheet;
+import org.apache.xalan.templates.ElemExtensionCall;
+import org.apache.xalan.templates.ElemTemplate;
+import org.apache.xalan.templates.ElemFunction;
+import org.apache.xalan.templates.ElemFuncResult;
+import org.apache.xalan.templates.ElemFallback;
+import org.apache.xalan.templates.ElemVariable;
+import org.apache.xalan.templates.ElemParam;
+import org.apache.xalan.templates.ElemValueOf;
+import org.apache.xalan.templates.ElemMessage;
+import org.apache.xalan.templates.ElemComment;
+import org.apache.xalan.templates.Constants;
+import org.apache.xpath.XPath;
+import org.apache.xalan.templates.StylesheetRoot;
+
+import javax.xml.transform.SourceLocator;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerConfigurationException;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import org.apache.xalan.res.XSLTErrorResources;
+
+
+/**
+ * <meta name="usage" content="internal"/>
+ * This class processes parse events for an exslt func:function element.
+ */
+public class ProcessorFunction extends ProcessorTemplateElem
+{
+
+  /**
+   * Start an ElemFunction. Verify that it is top level and that it has a name attribute with a
+   * namespace.
+   */
+  public void startElement(
+          StylesheetHandler handler, String uri, String localName, String rawName, Attributes attributes)
+            throws SAXException
+  {
+    //System.out.println("ProcessorFunction.startElement()");
+    String msg = "";
+    if (!(handler.getElemTemplateElement() instanceof StylesheetRoot))
+    {
+      msg = "func:function element must be top level.";
+      handler.error(msg, new SAXException(msg));
+    }
+    super.startElement(handler, uri, localName, rawName, attributes);
+       
+    String val = attributes.getValue("name");
+    int indexOfColon = val.indexOf(":");
+    if (indexOfColon > 0)
+    {
+      String prefix = val.substring(0, indexOfColon);
+      String localVal = val.substring(indexOfColon + 1);
+      String ns = handler.getNamespaceSupport().getURI(prefix);
+      //if (ns.length() > 0)
+      //  System.out.println("fullfuncname " + ns + localVal);
+    }
+    else
+    {
+      msg = "xsl:function name must have namespace";
+      handler.error(msg, new SAXException(msg));
+    }
+  }
+  
+  /**
+   * Must include; super doesn't suffice!
+   */
+  protected void appendAndPush(
+          StylesheetHandler handler, ElemTemplateElement elem)
+            throws SAXException
+  {
+    //System.out.println("ProcessorFunction appendAndPush()" + elem);
+    super.appendAndPush(handler, elem);
+    //System.out.println("originating node " + handler.getOriginatingNode());
+    elem.setDOMBackPointer(handler.getOriginatingNode());
+    handler.getStyleshe%t().setTemplate((ElemTemplate) elem);
+  }
+    
+  /**
+   * End an ElemFunction, and verify its validity.
+   */
+  public void endElement(
+          StylesheetHandler handler, String uri, String localName, String rawName)
+            throws SAXException
+  {
+   ElemTemplateElement function = handler.getElemTemplateElement();
+   SourceLocator locator = handler.getLocator();
+
+   // Validate
+   validate(function, handler);// may throw exception 
+            
+   super.endElement(handler, uri, localName, rawName);   
+  }
+  
+  /**
+   * Validate that the xsl:function contains children in the following order:
+   *  xsl:param*, xsl:variable* | xsl:message*, xsl:result. The only required 
+   * element is xsl:result, which must be the last child.
+   * Note: I assume xsl:comment is allowed anywhere.
+   */
+  public void validate(ElemTemplateElement elem, StylesheetHandler handler)
+    throws SAXException
+  {
+    String msg = "";
+    int result = 0; // Number of xsl:result elements.
+    int elemOrder = 0;
+    int lastElemOrder = 0;
+    boolean invalid = false;
+    elem = elem.getFirstChildElem();
+    while (elem != null)
+    {
+      if (elem.getXSLToken() == Constants.ELEMNAME_PARAMVARIABLE)
+        elemOrder = 0;
+      else if (elem.getXSLToken() == Constants.ELEMNAME_VARIABLE || 
+               elem.getXSLToken() == Constants.ELEMNAME_MESSAGE)
+        elemOrder = 1;
+      else if (elem.getXSLToken() == Constants.ELEMNAME_FUNCRESULT) 
+      {
+        elemOrder = 2;
+        if (++result > 1)
+        {
+          msg = "xsl:function cannot contain more than one xsl:result element.";
+          invalid = true;
+        }        
+      }
+      else if (elem.getXSLToken() != Constants.ELEMNAME_COMMENT)
+      {       
+        msg = "xsl:function contains invalid content.";
+        invalid = true;
+      }
+      if (elemOrder < lastElemOrder)
+      {
+        msg = "xsl:function elements do not appear in the proper order.";
+        invalid = true;
+      }      
+      elem = elem.getNextSiblingElem();
+      lastElemOrder = elemOrder;
+    }
+    if (result != 1)
+    {
+      msg = "The last element in an xsl:function must be an xsl:result.";
+      invalid = true;
+    }
+    if (invalid)
+      handler.error(msg, new SAXException(msg));    
+  }
+  
+}
\ No newline at end of file
diff --git a/src/org/apache/xalan/processor/ProcessorOutputElem.java b/src/org/apache/xalan/processor/ProcessorOutputElem.java
index 66599bb..30a936d 100644
--- a/src/org/apache/xalan/processor/ProcessorOutputElem.java
+++ b/src/org/apache/xalan/processor/ProcessorOutputElem.java
@@ -72,6 +72,7 @@
 
 import org.xml.sax.Attributes;
 
+
 /**
  * TransformerFactory for xsl:output markup.
  * @see <a href="http://www.w3.org/TR/xslt#dtd">XSLT DTD</a>
@@ -79,7 +80,7 @@
  */
 class ProcessorOutputElem extends XSLTElementProcessor
 {
-
+  
   /** The output properties, set temporarily while the properties are 
    *  being set from the attributes, and then nulled after that operation 
    *  is completed.  */
@@ -90,7 +91,7 @@
    * @see javax.xml.transform.OutputKeys#CDATA_SECTION_ELEMENTS
    * @param newValue non-null reference to processed attribute value.
    */
-  public void setCdataSectionElements(java.util.Vector newValue)
+  public void setCdataSectionElements(java.util.Vector newValue, QName qname)
   {
     m_outputProperties.setQNameProperties(OutputKeys.CDATA_SECTION_ELEMENTS, newValue);
   }
@@ -204,6 +205,18 @@
     QName key = new QName(attrUri, attrLocalName);
     m_outputProperties.setProperty(key, attrValue);
   }
+  
+  //XSLT 2.0
+ 
+  public void setName(QName v)
+  {
+    m_outputProperties.setQNameProperty("name", v);
+  }    
+  
+  public QName getName()
+  {
+    return m_outputProperties.getQNameProperty("name");
+  }
 
   /**
    * Receive notification of the start of an xsl:output element.
@@ -234,7 +247,7 @@
     m_outputProperties.setLocaterInfo(handler.getLocator());
     m_outputProperties.setUid(handler.nextUid());
     setPropertiesFromAttributes(handler, rawName, attributes, this);
-    
+
     // Access this only from the Hashtable level... we don't want to 
     // get default properties.
     String entitiesFileName =
@@ -254,7 +267,8 @@
       }
     }
     
-    handler.getStylesheet().setOutput(m_outputProperties);
+    // for 2.0, can have multiple output properties, identified by name.
+    handler.getStylesheet().setOutput(m_outputProperties); 
     
     ElemTemplateElement parent = handler.getElemTemplateElement();
     parent.appendChild(m_outputProperties);
diff --git a/src/org/apache/xalan/processor/ProcessorResultDocument.java b/src/org/apache/xalan/processor/ProcessorResultDocument.java
new file mode 100644
index 0000000..7d78fda
--- /dev/null
+++ b/src/org/apache/xalan/processor/ProcessorResultDocument.java
@@ -0,0 +1,117 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Xalan" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999, Lotus
+ * Development Corporation., http://www.lotus.com.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package org.apache.xalan.processor;
+
+import org.apache.xalan.templates.ElemTemplateElement;
+import org.apache.xalan.res.XSLTErrorResources;
+
+import javax.xml.transform.TransformerException;
+import org.xml.sax.Attributes;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.NoSuchMethodException;
+import java.lang.InstantiationException;
+import java.lang.IllegalAccessException;
+
+import java.util.Vector;
+
+import org.apache.xml.utils.QName;
+import org.apache.xalan.templates.Constants;
+import org.apache.xalan.templates.*;
+
+/**
+ * This class processes parse events for an XSLT template element.
+ * @see <a href="http://www.w3.org/TR/xslt#dtd">XSLT DTD</a>
+ * @see <a href="http://www.w3.org/TR/xslt#section-Creating-the-Result-Tree">section-Creating-the-Result-Tree in XSLT Specification</a>
+ */
+public class ProcessorResultDocument extends ProcessorTemplateElem
+{
+  public void startElement(
+          StylesheetHandler handler, String uri, String localName, String rawName, Attributes attributes)
+            throws org.xml.sax.SAXException
+  {
+    super.startElement(handler, uri, localName, rawName, attributes);
+    // validate? Cannot be owned by variable, parameter, message, what else?
+    if (localName.equals(Constants.ELEMNAME_PRINCIPALRESULTDOCUMENT_STRING))
+      validatePrincipal(handler);
+  }
+  
+  public void endElement(
+          StylesheetHandler handler, String uri, String localName, String rawName)
+            throws org.xml.sax.SAXException
+  {
+    super.endElement(handler, uri, localName, rawName);
+    // validate??
+  }
+  
+  /**
+   * This element must be a child of the Stylesheet.
+   */
+  private void validatePrincipal(StylesheetHandler handler)
+      throws org.xml.sax.SAXException    
+  {
+    ElemTemplateElement parent = handler.getElemTemplateElement().getParentElem();
+    //System.out.println("validatePrincipal parent " + parent);
+    if (!(parent instanceof StylesheetRoot))
+    {
+      String msg = "xsl:principal-result-document must be a top-level element.";
+      handler.error(msg, new org.xml.sax.SAXException(msg));
+    }
+  }
+
+}
\ No newline at end of file
diff --git a/src/org/apache/xalan/processor/XSLTSchema.java b/src/org/apache/xalan/processor/XSLTSchema.java
index b0fc4f9..5165864 100644
--- a/src/org/apache/xalan/processor/XSLTSchema.java
+++ b/src/org/apache/xalan/processor/XSLTSchema.java
@@ -86,6 +86,9 @@
 
     XSLTAttributeDef hrefAttr = new XSLTAttributeDef(null, "href",
                                   XSLTAttributeDef.T_URL, true);
+    XSLTAttributeDef hrefAttrOpt = new XSLTAttributeDef(null, "href",
+                                  XSLTAttributeDef.T_URL, false);
+    
     XSLTAttributeDef elementsAttr = new XSLTAttributeDef(null, "elements",
                                       XSLTAttributeDef.T_SIMPLEPATTERNLIST,
                                       true);
@@ -247,6 +250,20 @@
     XSLTAttributeDef xslVersionAttr =
       new XSLTAttributeDef(Constants.S_XSLNAMESPACEURL, "version",
                            XSLTAttributeDef.T_NMTOKEN, false);
+    //dml for result-document
+    XSLTAttributeDef resultDocFormatAttr =
+      new XSLTAttributeDef(null, "format",
+                           XSLTAttributeDef.T_QNAME, false);
+    // dml for output
+    XSLTAttributeDef includeContentTypeAttr = new XSLTAttributeDef(null,
+                                                   "include-content-type",
+                                                   XSLTAttributeDef.T_YESNO,
+                                                   false);
+    XSLTAttributeDef escapeUriAttributesAttr = new XSLTAttributeDef(null,
+                                                   "excape-uri-asttributes",
+                                                   XSLTAttributeDef.T_YESNO,
+                                                   false);
+    
     XSLTElementDef charData = new XSLTElementDef(this, null, "text()",
                                 null /*alias */, null /* elements */, null,  /* attributes */
                                 new ProcessorCharacters(),
@@ -267,9 +284,12 @@
     XSLTAttributeDef xslResultAttr =
       new XSLTAttributeDef(Constants.S_XSLNAMESPACEURL, "*",
                            XSLTAttributeDef.T_CDATA, false);
-    XSLTElementDef[] templateElements = new XSLTElementDef[21];
-    XSLTElementDef[] templateElementsAndParams = new XSLTElementDef[22];
-    XSLTElementDef[] templateElementsAndSort = new XSLTElementDef[22];
+    XSLTElementDef[] templateElements = new XSLTElementDef[24];
+    XSLTElementDef[] templateElementsAndParams = new XSLTElementDef[25];
+    XSLTElementDef[] templateElementsAndSort = new XSLTElementDef[25];
+    //exslt
+    XSLTElementDef[] exsltFunctionElements = new XSLTElementDef[25];// although should exclude some template elements.
+    
     XSLTElementDef[] charTemplateElements = new XSLTElementDef[15];
     XSLTElementDef resultElement = new XSLTElementDef(this, null, "*",
                                      null /*alias */,
@@ -282,7 +302,7 @@
                                        xslVersionAttr,
                                        xslResultAttr,
                                        resultAttr }, 
-																		 new ProcessorLRE(),
+                                        new ProcessorLRE(),
                                      ElemLiteralResult.class /* class object */, 20, true);
     XSLTElementDef unknownElement =
       new XSLTElementDef(this, "*", "unknown", null /*alias */,
@@ -293,14 +313,14 @@
                                                  xslVersionAttr,
                                                  xslResultAttr,
                                                  resultAttr }, 
-												 new ProcessorUnknown(),
-                         ElemUnknown.class /* class object */, 20, true);
+                                                 new ProcessorUnknown(),
+                                                 ElemUnknown.class /* class object */, 20, true);
     XSLTElementDef xslValueOf = new XSLTElementDef(this,
                                   Constants.S_XSLNAMESPACEURL, "value-of",
                                   null /*alias */, null /* elements */,
                                   new XSLTAttributeDef[]{ selectAttrRequired,
                                                           disableOutputEscapingAttr }, 
-																	new ProcessorTemplateElem(),
+                                               new ProcessorTemplateElem(),
                                   ElemValueOf.class /* class object */, 20, true);
     XSLTElementDef xslCopyOf = new XSLTElementDef(this,
                                  Constants.S_XSLNAMESPACEURL, "copy-of",
@@ -320,7 +340,7 @@
                                                          letterValueAttr,
                                                          groupingSeparatorAVT,
                                                          groupingSizeAttr }, 
-																 new ProcessorTemplateElem(),
+                                        new ProcessorTemplateElem(),
                                  ElemNumber.class /* class object */, 20, true);
 
     // <!-- xsl:sort cannot occur after any other elements or
@@ -335,7 +355,7 @@
                                                   dataTypeAttr,
                                                   orderAttr,
                                                   caseOrderAttr }, 
-																								new ProcessorTemplateElem(),
+                                       new ProcessorTemplateElem(),
                                                 ElemSort.class/* class object */, 19, true );
     XSLTElementDef xslWithParam = new XSLTElementDef(this,
                                     Constants.S_XSLNAMESPACEURL,
@@ -343,7 +363,7 @@
                                     templateElements /* elements */,  // %template;>
                                     new XSLTAttributeDef[]{ nameAttrRequired,
                                                             selectAttrOpt }, new ProcessorTemplateElem(),
-                                                                             ElemWithParam.class /* class object */);
+                                                                             ElemWithParam.class /* class object */, 19, true);
     XSLTElementDef xslApplyTemplates = new XSLTElementDef(this,
                                          Constants.S_XSLNAMESPACEURL,
                                          "apply-templates", null /*alias */,
@@ -351,7 +371,7 @@
                                                                xslWithParam } /* elements */, new XSLTAttributeDef[]{
                                                                  selectAttrDefNode,
                                                                  modeAttr }, 
-																				 new ProcessorTemplateElem(),
+                                                                        new ProcessorTemplateElem(),
                                          ElemApplyTemplates.class /* class object */, 20, true);
     XSLTElementDef xslApplyImports =
       new XSLTElementDef(this, Constants.S_XSLNAMESPACEURL, "apply-imports",
@@ -364,7 +384,7 @@
                                   null /*alias */, templateElementsAndSort,  // (#PCDATA %instructions; %result-elements; | xsl:sort)*
                                   new XSLTAttributeDef[]{ selectAttrRequired,
                                                           spaceAttr }, 
-																	new ProcessorTemplateElem(),
+                                               new ProcessorTemplateElem(),
                                   ElemForEach.class /* class object */, true, false, true, 20, true);
     XSLTElementDef xslIf = new XSLTElementDef(this,
                                               Constants.S_XSLNAMESPACEURL,
@@ -381,7 +401,7 @@
                                                   testAttrRequired,
                                                   spaceAttr }, new ProcessorTemplateElem(),
                                                                ElemWhen.class /* class object */,
-																															 false, true, 1, true);
+                                                                                                false, true, 1, true);
     XSLTElementDef xslOtherwise = new XSLTElementDef(this,
                                     Constants.S_XSLNAMESPACEURL, "otherwise",
                                     null /*alias */,
@@ -389,13 +409,13 @@
                                     new XSLTAttributeDef[]{ spaceAttr },
                                     new ProcessorTemplateElem(),
                                     ElemOtherwise.class /* class object */,
-																		false, false, 2, false);
+                                                       false, false, 2, false);
     XSLTElementDef xslChoose = new XSLTElementDef(this,
                                  Constants.S_XSLNAMESPACEURL, "choose",
                                  null /*alias */,
                                  new XSLTElementDef[]{ xslWhen,
                                                        xslOtherwise } /* elements */, 
-																 new XSLTAttributeDef[]{ spaceAttr },
+                                        new XSLTAttributeDef[]{ spaceAttr },
                                  new ProcessorTemplateElem(),
                                  ElemChoose.class /* class object */, true, false, true, 20, true);                                
     XSLTElementDef xslAttribute = new XSLTElementDef(this,
@@ -405,7 +425,7 @@
                                     new XSLTAttributeDef[]{ nameAVTRequired,
                                                             namespaceAVTOpt,
                                                             spaceAttr }, 
-																		new ProcessorTemplateElem(),
+                                    new ProcessorTemplateElem(),
                                     ElemAttribute.class /* class object */, 20, true);
     XSLTElementDef xslCallTemplate =
       new XSLTElementDef(this, Constants.S_XSLNAMESPACEURL, "call-template",
@@ -420,7 +440,7 @@
                                    templateElements /* elements */,  // %template;>
                                    new XSLTAttributeDef[]{ nameAttrRequired,
                                                            selectAttrOpt }, 
-																	 new ProcessorTemplateElem(),
+                                  new ProcessorTemplateElem(),
                                    ElemVariable.class /* class object */, 20, true);
     XSLTElementDef xslParam = new XSLTElementDef(this,
                                 Constants.S_XSLNAMESPACEURL, "param",
@@ -428,7 +448,7 @@
                                 templateElements /* elements */,  // %template;>
                                 new XSLTAttributeDef[]{ nameAttrRequired,
                                                         selectAttrOpt }, 
-																new ProcessorTemplateElem(),
+                                       new ProcessorTemplateElem(),
                                 ElemParam.class /* class object */, 19, true);
     XSLTElementDef xslText =
       new XSLTElementDef(this, Constants.S_XSLNAMESPACEURL, "text",
@@ -444,7 +464,7 @@
                          new XSLTAttributeDef[]{
                                                   nameAVTRequired,
                                                   spaceAttr }, 
-													new ProcessorTemplateElem(),
+                                        new ProcessorTemplateElem(),
                           ElemPI.class /* class object */, 20, true);
     XSLTElementDef xslElement = new XSLTElementDef(this,
                                   Constants.S_XSLNAMESPACEURL, "element",
@@ -454,7 +474,7 @@
                                                           namespaceAVTOpt,
                                                           useAttributeSetsAttr,
                                                           spaceAttr }, 
-																	new ProcessorTemplateElem(),
+                                               new ProcessorTemplateElem(),
                                   ElemElement.class /* class object */, 20, true);
     XSLTElementDef xslComment = new XSLTElementDef(this,
                                   Constants.S_XSLNAMESPACEURL, "comment",
@@ -469,7 +489,7 @@
                           new XSLTAttributeDef[]{
                                                   spaceAttr,
                                                   useAttributeSetsAttr }, 
-													new ProcessorTemplateElem(),
+                                        new ProcessorTemplateElem(),
                           ElemCopy.class /* class object */, 20, true);
     XSLTElementDef xslMessage = new XSLTElementDef(this,
                                   Constants.S_XSLNAMESPACEURL, "message",
@@ -485,8 +505,67 @@
                                    new XSLTAttributeDef[]{ spaceAttr },
                                    new ProcessorTemplateElem(),
                                    ElemFallback.class /* class object */, 20, true);
-    int i = 0;
+    //exslt
+    XSLTElementDef exsltFunction =
+                                  new XSLTElementDef(this, 
+                                  Constants.S_EXSLT_FUNCTIONS_URL, 
+                                  "function",
+                                  null /*alias */,
+                                  exsltFunctionElements /* elements */,
+                                  new XSLTAttributeDef[]{ nameAttrRequired },
+                                  new ProcessorExsltFunction(),
+                                  ElemExsltFunction.class /* class object */);
+    XSLTElementDef exsltResult =
+                                  new XSLTElementDef(this, 
+                                  Constants.S_EXSLT_FUNCTIONS_URL, 
+                                  "result",
+                                  null /*alias */,
+                                  templateElements /* elements */,
+                                  new XSLTAttributeDef[]{ selectAttrOpt },
+                                  new ProcessorExsltFuncResult(),
+                                  ElemExsltFuncResult.class  /* class object */);            
+    
+    //XSLT 2.0
+    XSLTElementDef xslResult =   new XSLTElementDef(this, 
+                                   Constants.S_XSLNAMESPACEURL,
+                                   "result",
+                                   null /*alias */,
+                                   templateElements /* elements */,
+                                   new XSLTAttributeDef[]{ selectAttrOpt },
+                                   new ProcessorFuncResult(),
+                                   ElemFuncResult.class  /* class object */);                
+    XSLTElementDef[] xslFunctionElements = new XSLTElementDef[]
+                                          {xslParam, xslVariable, 
+                                           xslMessage, xslComment, 
+                                           xslResult};                                                            
+    XSLTElementDef xslFunction = new XSLTElementDef(this,
+                                   Constants.S_XSLNAMESPACEURL,
+                                   "function",
+                                   null,
+                                   xslFunctionElements,
+                                   new XSLTAttributeDef[]{ nameAttrRequired },
+                                   new ProcessorFunction(),
+                                   ElemFunction.class /* class object */);
+    
+    XSLTElementDef xslPrincipalResultDocument = 
+                                 new XSLTElementDef(this,
+                                 Constants.S_XSLNAMESPACEURL, "principal-result-document",
+                                 null /*alias */,
+                                 templateElements,
+                                 new XSLTAttributeDef[]{resultDocFormatAttr, hrefAttrOpt},
+                                 new ProcessorResultDocument(),
+                                 ElemPrincipalResultDocument.class);
 
+    XSLTElementDef xslResultDocument = 
+                                 new XSLTElementDef(this,
+                                 Constants.S_XSLNAMESPACEURL, "result-document",
+                                 null /*alias */,
+                                 templateElements,
+                                 new XSLTAttributeDef[]{resultDocFormatAttr, hrefAttr},
+                                 new ProcessorResultDocument(),
+                                 ElemResultDocument.class);
+    
+    int i = 0;
     templateElements[i++] = charData;  // #PCDATA
 
     // char-instructions
@@ -512,22 +591,22 @@
     templateElements[i++] = xslAttribute;
     templateElements[i++] = resultElement;
     templateElements[i++] = unknownElement;
+    templateElements[i++] = xslResult;
+    templateElements[i++] = exsltResult;
+    templateElements[i++] = xslResultDocument; // May NOT appear in xslFunction or exsltFunction.
 
     int k;
 
     for (k = 0; k < i; k++)
     {
       templateElementsAndParams[k] = templateElements[k];
-    }
-
-    templateElementsAndParams[k] = xslParam;
-
-    for (k = 0; k < i; k++)
-    {
       templateElementsAndSort[k] = templateElements[k];
+      exsltFunctionElements[k]     = templateElements[k];
     }
-
+    templateElementsAndParams[k] = xslParam;
     templateElementsAndSort[k] = xslSort;
+    exsltFunctionElements[k]   = xslParam;
+
     i = 0;
     charTemplateElements[i++] = charData;  // #PCDATA
 
@@ -553,164 +632,184 @@
                                  new XSLTAttributeDef[]{ hrefAttr },  // EMPTY
                                  new ProcessorImport(),
                                  null /* class object */,
-																 1, true);
+                                        1, true);
     XSLTElementDef includeDef = new XSLTElementDef(this,
                                   Constants.S_XSLNAMESPACEURL, "include",
                                   null /*alias */, null /* elements */,  // EMPTY
                                   new XSLTAttributeDef[]{ hrefAttr },
                                   new ProcessorInclude(),
                                   null /* class object */,
-																	20, true);
-    XSLTElementDef[] topLevelElements = new XSLTElementDef[]{ includeDef,
-                                                              importDef,
-                                                              // resultElement,
-                                                              whiteSpaceOnly,
-                                                              unknownElement,
-                                                              new XSLTElementDef(
-                                                                this,
-                                                                Constants.S_XSLNAMESPACEURL,
-                                                                "strip-space",
-                                                                null /*alias */,
-                                                                null /* elements */,
-                                                                new XSLTAttributeDef[]{
-                                                                elementsAttr },
-                                                                new ProcessorStripSpace(),
-                                                                null /* class object */, 20, true),
-                                                              new XSLTElementDef(
-                                                                this,
-                                                                Constants.S_XSLNAMESPACEURL,
-                                                                "preserve-space",
-                                                                null /*alias */,
-                                                                null /* elements */,
-                                                                new XSLTAttributeDef[]{
-                                                                elementsAttr },
-                                                                new ProcessorPreserveSpace(),
-                                                                null /* class object */, 20, true),
-                                                              new XSLTElementDef(
-                                                                this,
-                                                                Constants.S_XSLNAMESPACEURL,
-                                                                "output",
-                                                                null /*alias */,
-                                                                null /* elements */,
-                                                                new XSLTAttributeDef[]{
-                                                                  methodAttr,
-                                                                  versionAttr,
-                                                                  encodingAttr,
-                                                                  omitXmlDeclarationAttr,
-                                                                  standaloneAttr,
-                                                                  doctypePublicAttr,
-                                                                  doctypeSystemAttr,
-                                                                  cdataSectionElementsAttr,
-                                                                  indentAttr,
-                                                                  mediaTypeAttr,
-                                                                  XSLTAttributeDef.m_foreignAttr }, 
-                                                                new ProcessorOutputElem(), null /* class object */, 20, true), 
-																				                      new XSLTElementDef(
-                                                                    this,
-                                                                    Constants.S_XSLNAMESPACEURL,
-                                                                    "key",
-                                                                    null /*alias */,
-                                                                    null /* elements */,  // EMPTY
-                                                                    new XSLTAttributeDef[]{ nameAttrRequired,
-                                                                                            matchAttrRequired,
-                                                                                            useAttr }, 
-																				                        new ProcessorKey(), null /* class object */, 20, true),
-                                                              new XSLTElementDef(
-                                                                this,
-                                                                Constants.S_XSLNAMESPACEURL,
-                                                                "decimal-format",
-                                                                null /*alias */,
-                                                                null /* elements */,  // EMPTY
-                                                                                 new XSLTAttributeDef[]{
-                                                                                   nameAttrOpt,
-                                                                                   decimalSeparatorAttr,
-                                                                                   groupingSeparatorAttr,
-                                                                                   infinityAttr,
-                                                                                   minusSignAttr,
-                                                                                   NaNAttr,
-                                                                                   percentAttr,
-                                                                                   perMilleAttr,
-                                                                                   zeroDigitAttr,
-                                                                                   digitAttr,
-                                                                                   patternSeparatorAttr }, 
-																				                        new ProcessorDecimalFormat(),
-                                                                null /* class object */, 20, true),
-                                                              new XSLTElementDef(
-                                                                this,
-                                                                Constants.S_XSLNAMESPACEURL,
-                                                                "attribute-set",
-                                                                null /*alias */,
-                                                                new XSLTElementDef[]{
-                                                                xslAttribute } /* elements */,
-                                                                new XSLTAttributeDef[]{
-                                                                  nameAttrRequired,
-                                                                  useAttributeSetsAttr }, new ProcessorAttributeSet(),
-                                                                                          null /* class object */, 20, true),
-                                                              new XSLTElementDef(
-                                                                this,
-                                                                Constants.S_XSLNAMESPACEURL,
-                                                                "variable",
-                                                                null /*alias */,
-                                                                templateElements /* elements */,
-                                                                new XSLTAttributeDef[]{
-                                                                  nameAttrRequired,
-                                                                  selectAttrOpt }, new ProcessorGlobalVariableDecl(),
-                                                                                   ElemVariable.class /* class object */, 20, true),
-                                                              new XSLTElementDef(
-                                                                this,
-                                                                Constants.S_XSLNAMESPACEURL,
-                                                                "param",
-                                                                null /*alias */,
-                                                                templateElements /* elements */,
-                                                                new XSLTAttributeDef[]{
-                                                                  nameAttrRequired,
-                                                                  selectAttrOpt }, new ProcessorGlobalParamDecl(),
-                                                                                   ElemParam.class /* class object */, 20, true),
-                                                              new XSLTElementDef(
-                                                                this,
-                                                                Constants.S_XSLNAMESPACEURL,
-                                                                "template",
-                                                                null /*alias */,
-                                                                templateElementsAndParams /* elements */,
-                                                                new XSLTAttributeDef[]{
-                                                                  matchAttrOpt,
-                                                                  nameAttrOpt,
-                                                                  priorityAttr,
-                                                                  modeAttr,
-                                                                  spaceAttr }, new ProcessorTemplate(), ElemTemplate.class /* class object */, 20, true), 
-																				                      new XSLTElementDef(
-                                                                    this,
-                                                                    Constants.S_XSLNAMESPACEURL,
-                                                                    "namespace-alias",
-                                                                    null /*alias */,
-                                                                    null /* elements */,  // EMPTY
-                                                                    new XSLTAttributeDef[]{ stylesheetPrefixAttr,
-                                                                                            resultPrefixAttr }, 
-																				                            new ProcessorNamespaceAlias(), null /* class object */, 20, true),
-                                                              new XSLTElementDef(
-                                                                this,
-                                                                Constants.S_BUILTIN_EXTENSIONS_URL,
-                                                                "component",
-                                                                null /*alias */,
-                                                                new XSLTElementDef[]{
-                                                                  new XSLTElementDef(
-                                                                    this,
-                                                                    Constants.S_BUILTIN_EXTENSIONS_URL,
-                                                                    "script",
-                                                                    null /*alias */,
-                                                                    new XSLTElementDef[]{ charData } /* elements */,
-                                                                    new XSLTAttributeDef[]{
-                                                                      new XSLTAttributeDef(
-                                                                        null,
-                                                                        "lang",
-                                                                        XSLTAttributeDef.T_NMTOKEN,
-                                                                        true),
-                                                                      new XSLTAttributeDef(null, "src", XSLTAttributeDef.T_URL, false) }, 
-																				                           new ProcessorLRE(),
-                                                                   ElemExtensionScript.class /* class object */, 20, true) },  // EMPTY
-                                                                                                                                                                                                                                                                                                                                                new XSLTAttributeDef[]{ new XSLTAttributeDef(null, "prefix", XSLTAttributeDef.T_NMTOKEN, true),
-                                                                                                                                                                                                                                                                                                                                                                        new XSLTAttributeDef(null, "elements", XSLTAttributeDef.T_STRINGLIST, false),
-                                                                                                                                                                                                                                                                                                                                                                        new XSLTAttributeDef(null, "functions", XSLTAttributeDef.T_STRINGLIST, false) }, new ProcessorLRE(), ElemExtensionDecl.class /* class object */) };
+                                               20, true);
+    
+    XSLTElementDef[] topLevelElements = new XSLTElementDef[]
+                                 {includeDef,
+                                  importDef,
+                                  // resultElement,
+                                  whiteSpaceOnly,
+                                  unknownElement,
+                                  new XSLTElementDef(
+                                         this,
+                                         Constants.S_XSLNAMESPACEURL,
+                                         "strip-space",
+                                         null /*alias */,
+                                         null /* elements */,
+                                         new XSLTAttributeDef[]{
+                                                elementsAttr },
+                                                new ProcessorStripSpace(),
+                                         null /* class object */, 20, true),
+                                  new XSLTElementDef(
+                                         this,
+                                         Constants.S_XSLNAMESPACEURL,
+                                         "preserve-space",
+                                         null /*alias */,
+                                         null /* elements */,
+                                         new XSLTAttributeDef[]{
+                                                 elementsAttr },
+                                                 new ProcessorPreserveSpace(),
+                                         null /* class object */, 20, true),
+                                  new XSLTElementDef(
+                                         this,
+                                         Constants.S_XSLNAMESPACEURL,
+                                         "output",
+                                         null /*alias */,
+                                         null /* elements */,
+                                         new XSLTAttributeDef[]{
+                                                  nameAttrOpt /*2.0-dml */, 
+                                                  methodAttr,
+                                                  versionAttr,
+                                                  encodingAttr,
+                                                  omitXmlDeclarationAttr,
+                                                  standaloneAttr,
+                                                  doctypePublicAttr,
+                                                  doctypeSystemAttr,
+                                                  cdataSectionElementsAttr,
+                                                  indentAttr,
+                                                  mediaTypeAttr,
+                                                  includeContentTypeAttr,
+                                                  escapeUriAttributesAttr,
+                                                  XSLTAttributeDef.m_foreignAttr },
+                                          new ProcessorOutputElem(), null /* class object */, 20, true), 
+                                  new XSLTElementDef(
+                                          this,
+                                          Constants.S_XSLNAMESPACEURL,
+                                          "key",
+                                          null /*alias */,
+                                          null /* elements */,  // EMPTY
+                                          new XSLTAttributeDef[]{ nameAttrRequired,
+                                                  matchAttrRequired,
+                                                  useAttr }, 
+                                          new ProcessorKey(), null /* class object */, 20, true),
+                                  new XSLTElementDef(
+                                          this,
+                                          Constants.S_XSLNAMESPACEURL,
+                                          "decimal-format",
+                                          null /*alias */,
+                                          null /* elements */,  // EMPTY
+                                          new XSLTAttributeDef[]{
+                                                  nameAttrOpt,
+                                                  decimalSeparatorAttr,
+                                                  groupingSeparatorAttr,
+                                                  infinityAttr,
+                                                  minusSignAttr,
+                                                  NaNAttr,
+                                                  percentAttr,
+                                                  perMilleAttr,
+                                                  zeroDigitAttr,
+                                                  digitAttr,
+                                                  patternSeparatorAttr }, 
+                                           new ProcessorDecimalFormat(),
+                                           null /* class object */, 20, true),
+                                  new XSLTElementDef(
+                                           this,
+                                           Constants.S_XSLNAMESPACEURL,
+                                           "attribute-set",
+                                           null /*alias */,
+                                           new XSLTElementDef[]{
+                                                   xslAttribute } /* elements */,
+                                           new XSLTAttributeDef[]{
+                                                   nameAttrRequired,
+                                                   useAttributeSetsAttr }, 
+                                           new ProcessorAttributeSet(),
+                                           null /* class object */, 20, true),
+                                  new XSLTElementDef(
+                                           this,
+                                           Constants.S_XSLNAMESPACEURL,
+                                           "variable",
+                                           null /*alias */,
+                                           templateElements /* elements */,
+                                           new XSLTAttributeDef[]{
+                                                   nameAttrRequired,
+                                                   selectAttrOpt }, 
+                                           new ProcessorGlobalVariableDecl(),
+                                           ElemVariable.class /* class object */, 20, true),
+                                  new XSLTElementDef(
+                                           this,
+                                           Constants.S_XSLNAMESPACEURL,
+                                           "param",
+                                           null /*alias */,
+                                           templateElements /* elements */,
+                                           new XSLTAttributeDef[]{
+                                                   nameAttrRequired,
+                                                   selectAttrOpt }, 
+                                           new ProcessorGlobalParamDecl(),
+                                           ElemParam.class /* class object */, 20, true),
+                                  new XSLTElementDef(
+                                           this,
+                                           Constants.S_XSLNAMESPACEURL,
+                                           "template",
+                                           null /*alias */,
+                                           templateElementsAndParams /* elements */,
+                                           new XSLTAttributeDef[]{
+                                                   matchAttrOpt,
+                                                   nameAttrOpt,
+                                                   priorityAttr,
+                                                   modeAttr,
+                                                   spaceAttr }, 
+                                           new ProcessorTemplate(), ElemTemplate.class /* class object */, true, 20, true), 
+                                  new XSLTElementDef(
+                                           this,
+                                           Constants.S_XSLNAMESPACEURL,
+                                           "namespace-alias",
+                                           null /*alias */,
+                                          null /* elements */,  // EMPTY
+                                           new XSLTAttributeDef[]{ 
+                                                   stylesheetPrefixAttr,
+                                                   resultPrefixAttr }, 
+                                           new ProcessorNamespaceAlias(), null /* class object */, 20, true),
+                                  new XSLTElementDef(
+                                           this,
+                                           Constants.S_BUILTIN_EXTENSIONS_URL,
+                                           "component",
+                                           null /*alias */,
+                                           new XSLTElementDef[]{
+                                                    new XSLTElementDef(
+                                                        this,
+                                                        Constants.S_BUILTIN_EXTENSIONS_URL,
+                                                        "script",
+                                                        null /*alias */,
+                                                    new XSLTElementDef[]{ 
+                                                        charData } /* elements */,
+                                                        new XSLTAttributeDef[]{
+                                                            new XSLTAttributeDef(
+                                                                null,
+                                                                "lang",
+                                                                XSLTAttributeDef.T_NMTOKEN,
+                                                                true),
+                                                            new XSLTAttributeDef(
+                                                                null, "src", XSLTAttributeDef.T_URL, false) }, 
+                                                                new ProcessorLRE(),
+                                                                ElemExtensionScript.class /* class object */, 20, true) },  // EMPTY
+                                                            new XSLTAttributeDef[]{ 
+                                                                new XSLTAttributeDef(
+                                                                    null, "prefix", XSLTAttributeDef.T_NMTOKEN, true),
+                                                                new XSLTAttributeDef(
+                                                                    null, "elements", XSLTAttributeDef.T_STRINGLIST, false),
+                                                                new XSLTAttributeDef(
+                                                                    null, "functions", XSLTAttributeDef.T_STRINGLIST, false) }, 
+                                                    new ProcessorLRE(), ElemExtensionDecl.class /* class object */),
+                                  exsltFunction, xslFunction/* exslt, stylesheet function*/,
+                                  xslPrincipalResultDocument};  //end of topevelElements
+    
     XSLTAttributeDef excludeResultPrefixesAttr =
       new XSLTAttributeDef(null, "exclude-result-prefixes",
                            XSLTAttributeDef.T_STRINGLIST, false);
diff --git a/src/org/apache/xalan/templates/ElemFuncResult.java b/src/org/apache/xalan/templates/ElemFuncResult.java
new file mode 100644
index 0000000..1ff34e2
--- /dev/null
+++ b/src/org/apache/xalan/templates/ElemFuncResult.java
@@ -0,0 +1,74 @@
+package org.apache.xalan.templates;
+
+//import org.w3c.dom.*;
+import org.apache.xml.dtm.DTM;
+
+import org.xml.sax.*;
+
+import org.apache.xpath.*;
+import org.apache.xpath.Expression;
+import org.apache.xpath.objects.XObjectFactory;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XString;
+import org.apache.xpath.objects.XRTreeFrag;
+import org.apache.xpath.objects.XRTreeFragSelectWrapper;
+import org.apache.xml.utils.QName;
+import org.apache.xalan.trace.SelectionEvent;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.transformer.TransformerImpl;
+
+import javax.xml.transform.TransformerException;
+
+/**
+ * Handles the xsl:result element within an xsl:function element.
+ */
+public class ElemFuncResult extends ElemVariable
+{
+ 
+  /**
+   * Generate the xsl:function return value, and assign it to the variable
+   * index slot assigned for it in ElemFunction compose().
+   * 
+   */
+  public void execute(TransformerImpl transformer) throws TransformerException
+  {    
+    XPathContext context = transformer.getXPathContext();
+    VariableStack varStack = context.getVarStack();
+    // ElemFunc result should always be the last child of an ElemFunction.
+    ElemFunction owner = this.getParentElem() instanceof ElemFunction ? 
+                         (ElemFunction)this.getParentElem() : null;
+    if (owner != null)
+    {
+      int resultIndex = owner.getResultIndex();
+      int sourceNode = context.getCurrentNode();
+      // Set the return value;
+      XObject var = getValue(transformer, sourceNode);   
+      varStack.setLocalVariable(resultIndex, var);
+    }    
+  }
+
+  /**
+   * Get an integer representation of the element type.
+   *
+   * @return An integer representation of the element, defined in the
+   *     Constants class.
+   * @see org.apache.xalan.templates.Constants
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_FUNCRESULT;
+  }
+  
+  /**
+   * Return the node name, defined in the
+   *     Constants class.
+   * @see org.apache.xalan.templates.Constants.
+   * @return The node name
+   * 
+   */
+   public String getNodeName()
+  {
+    return Constants.ELEMNAME_FUNCRESULT_STRING;
+  }
+
+}
diff --git a/src/org/apache/xalan/templates/ElemFunction.java b/src/org/apache/xalan/templates/ElemFunction.java
new file mode 100644
index 0000000..f35a342
--- /dev/null
+++ b/src/org/apache/xalan/templates/ElemFunction.java
@@ -0,0 +1,234 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Xalan" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999, Lotus
+ * Development Corporation., http://www.lotus.com.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package org.apache.xalan.templates;
+
+//import org.w3c.dom.*;
+import org.apache.xml.dtm.DTM;
+
+import org.xml.sax.*;
+
+import org.apache.xpath.*;
+import org.apache.xpath.Expression;
+import org.apache.xpath.objects.XObject;
+import org.apache.xpath.objects.XString;
+import org.apache.xpath.objects.XNumber;
+import org.apache.xpath.objects.XRTreeFrag;
+import org.apache.xpath.objects.XRTreeFragSelectWrapper;
+import org.apache.xml.utils.QName;
+import org.apache.xalan.trace.SelectionEvent;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.transformer.TransformerImpl;
+
+import org.apache.xalan.extensions.ExtensionsTable;
+
+import javax.xml.transform.TransformerException;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import org.apache.xalan.extensions.ExtensionNamespaceSupport;
+import org.apache.xalan.extensions.ExtensionHandlerExsltFunction;
+
+
+/**
+ * <meta name="usage" content="advanced"/>
+ * Implement func:function.
+ */
+public class ElemFunction extends ElemTemplate
+{
+  
+  /**
+   * Get an integer representation of the element type.
+   *
+   * @return An integer representation of the element, defined in the
+   *     Constants class.
+   * @see org.apache.xalan.templates.Constants
+   */
+  public int getXSLToken()
+  {
+    return Constants.ELEMNAME_FUNCTION;
+  }
+
+   /**
+   * Return the node name, defined in the
+   *     Constants class.
+   * @see org.apache.xalan.templates.Constants.
+   * @return The node name
+   * 
+   */ 
+  public String getNodeName()
+  {
+    return Constants.ELEMNAME_FUNCTION_STRING;
+  }
+  
+  public void execute(TransformerImpl transformer, XObject[] args)
+          throws TransformerException
+  {
+    XPathContext xctxt = transformer.getXPathContext();
+    VariableStack vars = xctxt.getVarStack();
+    
+    // Set parameters.
+    NodeList children = this.getChildNodes();
+    int numparams =0;
+    for (int i = 0; i < args.length; i ++)
+    {
+      Node child = children.item(i);
+      if (children.item(i) instanceof ElemParam)
+      {
+        numparams++;
+        ElemParam param = (ElemParam)children.item(i);
+        vars.setLocalVariable (param.m_index, args[i]);
+      }
+    }
+    if (numparams < args.length)
+      throw new TransformerException ("function called with too many args");
+
+    //  Removed ElemTemplate 'push' and 'pop' of RTFContext, in order to avoid losing the RTF context 
+    //  before a value can be returned. ElemFunction operates in the scope of the template that called 
+    //  the function.
+    //  xctxt.pushRTFContext();
+    
+    if (TransformerImpl.S_DEBUG)
+      transformer.getTraceManager().fireTraceEvent(this);
+    
+    // Be sure the return value is not set (so can verify that only one result
+    // is generated per ElemFunction execute).
+    vars.setLocalVariable(_resultIndex, null);
+    transformer.executeChildTemplates(this, true); 
+
+    if (TransformerImpl.S_DEBUG)
+      transformer.getTraceManager().fireTraceEndEvent(this);
+    
+    // Following ElemTemplate 'pop' removed -- see above.
+    // xctxt.popRTFContext(); 
+    
+  }
+  //int m_inArgsSize;
+  //public int m_frameSize;  
+  
+  /**
+   * Called after everything else has been
+   * recomposed, and allows the function to set remaining
+   * values that may be based on some other property that
+   * depends on recomposition. Also adds a slot to the variable
+   * stack for the return value. The result element will place
+   * its value in this slot.
+   */
+  public void compose(StylesheetRoot sroot) throws TransformerException
+  {
+    super.compose(sroot);
+    StylesheetRoot.ComposeState cstate = sroot.getComposeState();
+    // Add a position on the variable stack for the return value.
+    setResultIndex(cstate.addVariableName
+      (new QName(Constants.S_XSLNAMESPACEURL, "result")));
+    
+    // Register the function namespace (if not already registered).
+    // Note: if regsitered for EXSLT, override; cannot be overriden by EXSLT.
+    String namespace = getName().getNamespace();
+    String handlerClass = "org.apache.xalan.extensions.ExtensionHandlerStylesheetFunction";    
+    Object[] args ={namespace, sroot};
+    ExtensionNamespaceSupport extNsSpt = 
+                         new ExtensionNamespaceSupport(namespace, handlerClass, args);
+    sroot.getExtensionNamespacesManager().registerExtension(extNsSpt);
+  }
+  
+  /**
+   * Add the namespace to the StylesheetRoot vector of extension namespaces. Be sure the
+   * exslt:function namespace is also added.
+   */
+/*  public void runtimeInit(TransformerImpl transformer) throws TransformerException
+  {
+    //System.out.println("elemFunction.runtimeInit()");
+    String namespace = getName().getNamespace();
+    ExtensionsTable etable = transformer.getExtensionsTable();
+    StylesheetRoot sroot = transformer.getStylesheet();
+    ExtensionHandlerExsltFunction exsltHandler =
+             new ExtensionHandlerExsltFunction(namespace, sroot);
+    //etable.addExtensionNamespace(namespace, exsltHandler);
+    // Make sure there is a handler for the EXSLT functions namespace
+    // -- for isElementAvailable().
+    if (!(namespace.equals(Constants.S_EXSLT_FUNCTIONS_URL)))
+    {
+      exsltHandler = new ExtensionHandlerExsltFunction(
+                                   Constants.S_EXSLT_FUNCTIONS_URL, 
+                                   sroot);
+     // etable.addExtensionNamespace(Constants.S_EXSLT_FUNCTIONS_URL, 
+     //                              exsltHandler);
+    }
+  }
+*/  
+
+  private int _resultIndex;
+  
+  /**
+   * Sets aside a position on the local variable stack index 
+   * to refer to the result element return value.
+   */
+  void setResultIndex(int stackIndex)
+  { 
+      _resultIndex = stackIndex;
+  }
+  
+  /**
+   * Provides the EXSLT extension handler access to the return value.
+   */
+  public int getResultIndex()
+  {
+    return _resultIndex;
+  }
+  
+}
\ No newline at end of file
diff --git a/src/org/apache/xalan/templates/ElemPrincipalResultDocument.java b/src/org/apache/xalan/templates/ElemPrincipalResultDocument.java
new file mode 100644
index 0000000..768dd3e
--- /dev/null
+++ b/src/org/apache/xalan/templates/ElemPrincipalResultDocument.java
@@ -0,0 +1,273 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Xalan" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999, Lotus
+ * Development Corporation., http://www.lotus.com.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package org.apache.xalan.templates;
+
+import java.lang.InstantiationException;
+
+import java.io.Serializable;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+// Xalan imports
+import org.apache.xml.utils.UnImplNode;
+import org.apache.xml.utils.NameSpace;
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xml.utils.QName;
+import org.apache.xml.utils.StringToStringTable;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xalan.transformer.ResultNameSpace;
+import org.apache.xalan.transformer.ResultTreeHandler;
+import org.apache.xpath.VariableStack;
+import org.apache.xpath.WhitespaceStrippingElementMatcher;
+import org.apache.xpath.ExpressionNode;
+
+// TRaX imports
+import javax.xml.transform.Templates;
+import javax.xml.transform.SourceLocator;
+
+// DOM Imports
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.apache.xml.dtm.DTM;
+
+// SAX Imports
+import org.xml.sax.Locator;
+import javax.xml.transform.TransformerException;
+
+import org.xml.sax.helpers.NamespaceSupport;
+import org.apache.xml.utils.NamespaceSupport2;
+import org.xml.sax.ContentHandler;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileNotFoundException;
+import javax.xml.transform.Result;
+import javax.xml.transform.stream.StreamResult;
+
+import java.util.Properties;
+
+/**
+ * <meta name="usage" content="advanced"/>
+ * An instance of this class represents an element inside
+ * an xsl:template class.  It has a single "execute" method
+ * which is expected to perform the given action on the
+ * result tree.
+ * This class acts like a Element node, and implements the
+ * Element interface, but is not a full implementation
+ * of that interface... it only implements enough for
+ * basic traversal of the tree.
+ *
+ * @see Stylesheet
+ */
+public class ElemPrincipalResultDocument extends ElemTemplateElement
+{
+  
+  /**
+   * The value of the "format" attribute.
+   * @serial
+   */
+  protected QName m_qname;
+  
+  protected String m_href;
+
+  /**
+   * Set the "name" attribute.
+   * Both xsl:variable and xsl:param have a required name
+   * attribute, which specifies the name of the variable. The
+   * value of the name attribute is a QName, which is expanded
+   * as described in [2.4 Qualified Names].
+   * @see <a href="http://www.w3.org/TR/xslt#qname">qname in XSLT Specification</a>
+   *
+   * @param v Value to set for the "format" attribute.
+   */
+  public void setFormat(QName v)
+  {
+    m_qname = v;
+  }
+
+  /**
+   * Get the "name" attribute.
+   * Both xsl:variable and xsl:param have a required name
+   * attribute, which specifies the name of the variable. The
+   * value of the name attribute is a QName, which is expanded
+   * as described in [2.4 Qualified Names].
+   * @see <a href="http://www.w3.org/TR/xslt#qname">qname in XSLT Specification</a>
+   *
+   * @return Value of the "format" attribute.
+   */
+  public QName getFormat()
+  {
+    return m_qname;
+  }
+  
+  public void setHref(String v)
+  {
+    m_href = v;
+  }
+  
+  public String getHref()
+  {
+    return m_href;
+  }
+  
+  private OutputProperties m_outputProperties;
+  
+  public void compose(StylesheetRoot sroot) throws TransformerException
+  {
+    //System.out.println("ElemPrincipalResultDocument.compose()-- format " + getFormat());  
+    super.compose(sroot);
+    m_outputProperties = sroot.getOutputComposed(getFormat());
+    // set primary output properties for the stylesheet.
+    sroot.setOutputProperties(m_outputProperties);
+  }
+ 
+  // runtimeInit() is called; execute() is not. Seems like a little overkill setting output props 
+  // and content handler, but anything less doesn't seem to work.
+  public void runtimeInit(TransformerImpl transformer) throws TransformerException
+  {
+    //System.out.println("ElemPrincipalResultDocument.runtimeInit()");
+    transformer.setOutputFormat(m_outputProperties);
+    String fileName = "primary.out";
+    try
+    {
+      if (null != getHref())
+      {
+        fileName = urlToFileName(getHref());
+      }
+      File file = new File(fileName);
+      if (!(file.isAbsolute()))
+      {
+        fileName = makeAbsolute(fileName, transformer);
+        file = new File(fileName);
+      }
+      if (transformer.OutputFileAlreadyUsed(fileName)) // should never be true.
+          throw new TransformerException("Output file already used -- " + fileName);
+      
+      String dirStr = file.getParent();
+      if((null != dirStr) && (dirStr.length() > 0))
+      {
+        File dir = new File(dirStr);
+        dir.mkdirs();
+      }
+      
+      Result primaryResult = new StreamResult(new FileOutputStream(file));
+      // Be sure to set system ID; used for setting base for secondary 
+      // output documents.
+      primaryResult.setSystemId(getHref());
+      transformer.setOutputTarget(primaryResult);
+      ContentHandler primaryHandler = transformer.createResultContentHandler
+                                           (primaryResult, m_outputProperties);
+      transformer.setContentHandler(primaryHandler);
+    }
+    catch (FileNotFoundException fe)
+    {
+      throw new TransformerException(fe);
+    }    
+  }
+  
+  /**
+   * Based on Redirect, which questions its use!
+   * In addition to purging "file" scheme (as in
+   * Redirect), also adjusts the file separator.
+   * Static so can be called from ElemResultDocument for
+   * managing secondary output documents.
+   */
+  protected static String urlToFileName(String url)
+  {
+    String fileName = url;
+      if(null != url)
+    {        
+      if(url.startsWith("file:////"))
+        fileName = url.substring(7);
+      else if(url.startsWith("file:///"))
+        fileName = url.substring(6);
+      else if(url.startsWith("file://"))
+        fileName = url.substring(5);
+      else if(url.startsWith("file:/"))
+        fileName = url.substring(5);
+      else if(url.startsWith("file:"))
+        fileName = url.substring(4);
+      
+      if (File.separatorChar != '/')
+        fileName = fileName.replace(File.separatorChar, '/');
+    }
+    return fileName;
+  }
+  
+  protected static String makeAbsolute(String fileName, TransformerImpl transformer)
+  {
+    String base = "";
+    Result outputTarget = transformer.getOutputTarget();
+    if ( (null != outputTarget) && ((base = outputTarget.getSystemId()) != null) ) 
+    {
+      base = ElemPrincipalResultDocument.urlToFileName(base);
+    }
+    else
+    {
+      base = ElemPrincipalResultDocument.urlToFileName(transformer.getBaseURLOfSource());
+    }
+    File file = new File(base).getAbsoluteFile();
+    String baseDir = file.getParent();
+    return baseDir + File.separator + fileName;
+  }  
+
+}
diff --git a/src/org/apache/xalan/templates/ElemResultDocument.java b/src/org/apache/xalan/templates/ElemResultDocument.java
new file mode 100644
index 0000000..d766137
--- /dev/null
+++ b/src/org/apache/xalan/templates/ElemResultDocument.java
@@ -0,0 +1,256 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:  
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Xalan" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation and was
+ * originally based on software copyright (c) 1999, Lotus
+ * Development Corporation., http://www.lotus.com.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+package org.apache.xalan.templates;
+
+import java.lang.InstantiationException;
+
+import java.io.Serializable;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+// Xalan imports
+import org.apache.xml.utils.UnImplNode;
+import org.apache.xml.utils.NameSpace;
+import org.apache.xml.utils.PrefixResolver;
+import org.apache.xml.utils.QName;
+import org.apache.xml.utils.StringToStringTable;
+import org.apache.xalan.res.XSLTErrorResources;
+import org.apache.xalan.res.XSLMessages;
+import org.apache.xalan.transformer.TransformerImpl;
+import org.apache.xalan.transformer.ResultNameSpace;
+import org.apache.xalan.transformer.ResultTreeHandler;
+import org.apache.xpath.VariableStack;
+import org.apache.xpath.WhitespaceStrippingElementMatcher;
+import org.apache.xpath.ExpressionNode;
+import org.apache.xpath.XPathContext;
+
+// TRaX imports
+import javax.xml.transform.Templates;
+import javax.xml.transform.SourceLocator;
+
+// DOM Imports
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.apache.xml.dtm.DTM;
+
+// SAX Imports
+import org.xml.sax.Locator;
+import javax.xml.transform.TransformerException;
+import org.xml.sax.ContentHandler;
+
+import org.xml.sax.helpers.NamespaceSupport;
+import org.apache.xml.utils.NamespaceSupport2;
+
+import java.util.Properties;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileNotFoundException;
+import javax.xml.transform.Result;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.xalan.templates.*;
+
+/**
+ * <meta name="usage" content="advanced"/>
+ * An instance of this class represents an element inside
+ * an xsl:template class.  It has a single "execute" method
+ * which is expected to perform the given action on the
+ * result tree.
+ * This class acts like a Element node, and implements the
+ * Element interface, but is not a full implementation
+ * of that interface... it only implements enough for
+ * basic traversal of the tree.
+ *
+ * @see Stylesheet
+ */
+public class ElemResultDocument extends ElemTemplateElement
+{
+  
+  /**
+   * The value of the "format" attribute.
+   * @serial
+   */
+  protected QName m_qname;
+  
+  protected String m_href;
+
+  /**
+   * Set the "name" attribute.
+   * Both xsl:variable and xsl:param have a required name
+   * attribute, which specifies the name of the variable. The
+   * value of the name attribute is a QName, which is expanded
+   * as described in [2.4 Qualified Names].
+   * @see <a href="http://www.w3.org/TR/xslt#qname">qname in XSLT Specification</a>
+   *
+   * @param v Value to set for the "format" attribute.
+   */
+  public void setFormat(QName v)
+  {
+    m_qname = v;
+  }
+
+  /**
+   * Get the "name" attribute.
+   * Both xsl:variable and xsl:param have a required name
+   * attribute, which specifies the name of the variable. The
+   * value of the name attribute is a QName, which is expanded
+   * as described in [2.4 Qualified Names].
+   * @see <a href="http://www.w3.org/TR/xslt#qname">qname in XSLT Specification</a>
+   *
+   * @return Value of the "format" attribute.
+   */
+  public QName getFormat()
+  {
+    return m_qname;
+  }
+  
+  public void setHref(String v)
+  {
+    m_href = v;
+  }
+  
+  public String getHref()
+  {
+    return m_href;
+  }
+
+  private OutputProperties m_outputProperties;
+  
+  public void compose(StylesheetRoot sroot) throws TransformerException
+  {
+    //System.out.println("ElemResultDocument.compose()-- format " + getFormat());  
+    super.compose(sroot);
+    m_outputProperties = sroot.getOutputComposed(getFormat());
+    //System.out.println("ElemResultDocument.compose()-- m_outputProperties " +m_outputProperties);
+  }
+
+  public void execute(
+          TransformerImpl transformer)
+            throws TransformerException
+  {
+    //System.out.println("ElemResultDocument.execute()");
+    validate(this.getParentElem());
+    
+    OutputProperties primaryOutProps = transformer.getOutputFormat();
+    transformer.setOutputFormat(m_outputProperties);
+    String fileName = ElemPrincipalResultDocument.urlToFileName(getHref());
+    try
+    {
+      File file = new File(fileName);
+      if (!(file.isAbsolute()))
+      {
+        fileName = ElemPrincipalResultDocument.makeAbsolute(fileName, transformer);
+        file = new File(fileName);
+      }
+      if (transformer.OutputFileAlreadyUsed(fileName))
+        throw new TransformerException("Output file already used -- " + fileName);
+      
+      String dirStr = file.getParent();    
+      if((null != dirStr) && (dirStr.length() > 0))
+      {
+        File dir = new File(dirStr);
+        dir.mkdirs();
+      }
+      
+      Result secondaryResult = new StreamResult(new FileOutputStream(file));
+      ContentHandler primaryHandler = transformer.getContentHandler();
+      ContentHandler secondaryHandler = transformer.createResultContentHandler(secondaryResult);
+      secondaryHandler.startDocument();
+      transformer.executeChildTemplates(this, secondaryHandler);
+      secondaryHandler.endDocument();
+      transformer.setContentHandler(primaryHandler);
+    }
+    catch (Exception e)//FileNotFoundException, SAXException
+    {
+      throw new TransformerException(e);
+    }
+    finally
+    {
+     transformer.setOutputFormat (primaryOutProps);
+    }   
+  }
+  
+  /**
+   * Not sure at this point how to fully verify that the current result
+   * tree is not a "temporary result tree." In any case, placed the test here,
+   * rather than in ProcessorResultDocument.startElement() because checking for
+   * what the spec identifies as a "dynamic" error.
+   */
+  private void validate(ElemTemplateElement ancestor)
+    throws TransformerException
+  {
+    while (ancestor != null && !(ancestor instanceof ElemTemplate))
+    {System.out.println("validate " + ancestor);
+      if (ancestor instanceof ElemVariable 
+          || ancestor instanceof ElemParam
+          || ancestor instanceof ElemMessage
+          || ancestor instanceof ElemAttribute
+          || ancestor instanceof ElemAttributeSet
+          || ancestor instanceof ElemFunction
+          || ancestor instanceof ElemExsltFunction)
+      {
+        String msg = "xsl:result-document cannot be used in this context.";
+        throw new TransformerException(msg);
+      }
+      ancestor = ancestor.getParentElem();
+    }
+  }
+  
+}
\ No newline at end of file
diff --git a/src/org/apache/xalan/templates/StylesheetRoot.java b/src/org/apache/xalan/templates/StylesheetRoot.java
index db43f1b..5e71b59 100644
--- a/src/org/apache/xalan/templates/StylesheetRoot.java
+++ b/src/org/apache/xalan/templates/StylesheetRoot.java
@@ -89,6 +89,11 @@
 import javax.xml.transform.ErrorListener;
 
 import org.apache.xml.dtm.ref.ExpandedNameTable;
+//dml
+import org.apache.xml.utils.StringVector;
+import org.apache.xalan.extensions.ExtensionNamespaceSupport;
+import org.apache.xalan.extensions.ExtensionHandler;
+import org.apache.xalan.extensions.ExtensionNamespacesManager;
 
 /**
  * <meta name="usage" content="general"/>
@@ -126,7 +131,7 @@
    * @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.
@@ -139,7 +144,6 @@
 
     this(listener);
     m_availElems = schema.getElemsAvailable();
-
   }
 
   /**
@@ -162,6 +166,39 @@
   {
     return m_availElems;
   }
+  
+  private 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 ================
 
@@ -243,12 +280,8 @@
         // 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++)
@@ -303,7 +336,10 @@
         composeTemplates(included);
       }
     }
-    
+    // Attempt to register any remaining unregistered extension namespaces.
+    if (m_extNsMgr != null)
+      m_extNsMgr.registerUnregisteredNamespaces();
+
     clearComposeState();
   }
 
@@ -447,7 +483,14 @@
    * will be set as stylesheets are encountered.
    * @serial
    */
-  private OutputProperties m_outputProperties;
+  private OutputProperties m_outputProperties; // Keep for time being?? 
+  // Can set from ElemPrincipalResultDocument.
+  protected void setOutputProperties(OutputProperties primaryProps)
+  {
+    m_outputProperties = primaryProps;
+  }
+  
+  private Hashtable m_outputPropertiesTable = new Hashtable();
 
   /**
    * Recompose the output format object from the included elements.
@@ -457,8 +500,25 @@
   void recomposeOutput(OutputProperties oprops)
     throws TransformerException
   {
+    //System.out.println("StylesheetRoot.recomposeOutput() " + oprops.getName());
+    // put into m_outputPropertiesTable
     
-    m_outputProperties.copyFrom(oprops);
+    Object key = (oprops.getName() != null)
+                  ? (Object)oprops.getName(): (Object)new String("") ;
+    
+    if (m_outputPropertiesTable.containsKey(key))
+    {
+      //System.out.println("has key " + key);
+      ((OutputProperties)m_outputPropertiesTable.get(key)).copyFrom(oprops);
+    }
+    else
+    { 
+      //System.out.println("new key " + key);
+      OutputProperties outputProps = new OutputProperties(Method.XML);
+      outputProps.copyFrom(oprops);
+      m_outputPropertiesTable.put(key, outputProps);
+    }
+    //m_outputProperties.copyFrom(oprops);
   }
 
   /**
@@ -479,7 +539,19 @@
     // System.out.println("getOutputComposed.getIndenting: "+m_outputProperties.getIndenting());
     return m_outputProperties;
   }
+  
+  //dml
+  public OutputProperties getOutputComposed(QName qname)
+  {
+    Object key = (qname != null)
+                  ? (Object)qname : (Object)new String("") ;
+    OutputProperties oprops = (OutputProperties)m_outputPropertiesTable.get(key);
+    
+    return oprops;
+  }
 
+  // following flag must be changed to include QName param.
+  
   /** Flag indicating whether an output method has been set by the user.
    *  @serial           */
   private boolean m_outputMethodSet = false;